Data
Sorry for all of the packages. They grew and grew and grew, and I don’t want to refactor everything to reduce the dependencies.
library(raster)
library(data.table)
library(sf)
#RStoolbox has some dependencies like openMP that can be difficult to compile on a Mac (needed for the dependent package "caret"). If you have High Sierra OS or newer, search for instructions specific to your OS- it's a lot easier than older OS's.
library(RStoolbox)
library(leaflet)
library(plotly)
library(gdata)
library(BSDA)
library(ade4)
library(readxl)
library(janitor)
library(rnaturalearth)
library(adehabitatHS)
library(climateStability)
library(htmlwidgets)
library(tidyverse)
library(ggspatial)
library(here)
library(mapview)
library(fs)
# source locality plotting function
source(here::here("R", "plot_leaflet_function.R"))
# source climate pca plotting function
source(here::here("R", "plot_climate_pca_function.R"))
# source species pca plotting function
source(here::here("R", "species_pca_function.R"))
# source function that creates a minimum convex polygon around points
source(here::here("R", "min_convex_poly.R"))
source(here::here("R", "enfa_calc_function.R"))
source(here::here("R", "marginality_lollipop_plot.R"))
source(here::here("R", "presence_absence_raster_function.R"))
source(here::here("R", "crop_background_env_function.R"))
source(here::here("R", "enfa_hex_plot.R"))
source(here::here("R", "total_climate_pca_plot.R"))
source(here::here("R", "raster_correlation_function.R"))
source(here::here("R", "move_to_species.R"))
Create subdirectories (if needed) and establish paths.
[1] "Directory already there."
[1] "Directory already there."
[1] "Directory already there."
[1] "Directory already there."
[1] "Directory already there."
[1] "Directory already there."
[1] "Directory already there."
[1] "Directory already there."
[1] "Directory already there."
Read in the spreadsheet and take a look at the data.
# data path
loc_path <- here::here("data", "all species New_6-14-19.xlsx")
# species list
species_list <- c("horridus",
"hookeri",
"annulata",
"ovobessus",
"huttoni",
"jucundum")
### read in spreadsheet
loc <- read_xlsx(loc_path) %>%
janitor::clean_names() %>%
mutate(reproductive_mode = as.factor(reproductive_mode)) %>%
filter(species %in% species_list)
#get the number of individuals, and the sexuality counts per species
count_repro_mode <- loc %>%
group_by(genus, species, reproductive_mode) %>%
dplyr::count() %>%
mutate(genus_species = str_c(genus, species, sep = "_"),
genus_species = str_replace_all(genus_species, " ", "_"),
genus_species = str_replace_all(genus_species, "\\.", "")) %>%
ungroup() %>%
mutate(genus_species = fct_reorder(genus_species, n, sum)) %>%
ggplot(aes(x = genus_species, y = n, fill = reproductive_mode)) +
geom_col() +
coord_flip() +
theme_minimal()
count_repro_mode

Map
Plot a leaflet map of the localities. The leaflet map is interactive. You can click on the localities and a flag with some metadata will pop up!
PCA-Genera
Climate Data
Read in the bioclim layers for analysis. I’m using all 19 for this preliminary exploration. I’m using CHELSA v1.2 data downloaded from their website. Plotting the first temperature layer to take a look at the data.
PCA by locality
This is a PCA of the climate data extracted for each locality, rather than a PCA of the total climate space. This gives us a general idea of differences in environmental niche.
Run the pca and check out variable loadings and proportion of variance explained by components.
Two plots: One plot of the PCA colored according to genus, with convex hulls surrounding the genera. It looks like this reflects a latitudinal gradient in temperature! You can interact with the PCA plot by clicking on points to view associated metadata. You can isolate the genus you want to view by double clicking the genus in the legend! You can also remove a genus by clicking on it once. There’s some other functionality you can explore in the toolbar at the top of the plot. The second plot is a PCA colored according to reproductive mode. It looks like asexual populations occupy slightly larger niche space, but both reproductive modes have a similar niche center.
Stability
Examining whether asexual populations occupy more unstable climates than sexual populations. Only using species with multiple sexual and asexual populations. Asexual pops tend to occupy more stable temperature environments, but less stable precipitation environments. We’re estimating stability using the method presented by Owens and Guralnick 2019- climateStability: AN R PACKAGE TO ESTIMATE CLIMATE STABILITY FROM TIME-SLICE CLIMATOLOGIES.
### Creating temperature and precipitation stability layers
### Using bio1 (average temp) and bio12 (average precip)
### 2.5 arcmin resolution, already cropped to NZ to speed up computation time
# time slices are calculated as the difference between the midpoints of the two time periods the climate layers were calculated for (e.g. midpoint of LH = (4.2 ka - 0.3 ka) / 2 + 0.3 ka = 2.25, midpoint of MH = (8.326 ka - 4.2 ka) / 2 + 4.2 = 6.263. time_slice = 6.263 - 2.25 = 4.013)
# c = current
# t_lh = midpoint time for late holocene
# t_mh = mid-Holocene
# t_eh = early-Holocene
# t_yds = Younger Dryas Stadial
# t_ba = Bølling-Allerød
# t_hs = Heinrich Stadial 1
# t_lgm = Last Glacial Maximum
c <- (2013 - 1979) / 2
t_lh <- ((4.2 - 0.3) / 2 + 0.3) * 1000
t_mh <- ((8.326 - 4.2) / 2 + 4.2) * 1000
t_eh <- ((11.7 - 8.326) / 2 + 8.326) * 1000
t_yds <- ((12.9 - 11.7) / 2 + 11.7) * 1000
t_ba <- ((14.7 - 12.9) / 2 + 12.9) * 1000
t_hs <- ((17 - 14.7) / 2 + 14.7) * 1000
t_lgm <- 21000
time_slices <- c(t_lh - c,
t_mh - t_lh,
t_eh - t_mh,
t_yds - t_eh,
t_ba - t_yds,
t_hs - t_ba,
t_lgm - t_hs)
precip_deviation <-
climateStability::deviationThroughTime(variableDirectory = precip_path, timeSlicePeriod = time_slices)
precip_stability <- (1 / precip_deviation)
precip_stability_scaled <- climateStability::rescale0to1(precip_stability)
# write precipitation stability to file
writeRaster(
precip_stability_scaled,
filename = file.path(raster_path, "precip_stability_scaled.tif"),
format = "GTiff",
overwrite = TRUE
)
temp_deviation <-
climateStability::deviationThroughTime(variableDirectory = temp_path, timeSlicePeriod = time_slices)
temp_stability <- (1 / temp_deviation)
temp_stability_scaled <- climateStability::rescale0to1(temp_stability)
# write temperature stability to file
writeRaster(
temp_stability_scaled,
filename = file.path(raster_path, "temp_stability_scaled.tif"),
format = "GTiff",
overwrite = TRUE
)
overall_stability_scaled <- precip_stability_scaled * temp_stability_scaled
# write overall stability to file
writeRaster(
overall_stability_scaled,
filename = file.path(raster_path, "overall_stability_scaled.tif"),
format = "GTiff",
overwrite = TRUE
)
temp_stability_map <- ggplot() +
ggspatial::layer_spatial(data = temp_stability_scaled) +
labs(title = "Temperature stability") +
scale_fill_viridis_c(na.value = "transparent") +
theme_minimal()
precip_stability_map <- ggplot() +
ggspatial::layer_spatial(data = precip_stability_scaled) +
labs(title = "Precipitation stability") +
scale_fill_viridis_c(na.value = "transparent") +
theme_minimal()
overall_stability_map <- ggplot() +
ggspatial::layer_spatial(data = overall_stability_scaled) +
labs(title = "Overall stability") +
scale_fill_viridis_c(na.value = "transparent") +
theme_minimal()
temp_stability_map
precip_stability_map
overall_stability_map
ggsave("temp_stability.png",
plot = temp_stability_map,
device = "png",
path = map_path,
dpi = "retina")
ggsave("precip_stability.png",
plot = precip_stability_map,
device = "png",
path = map_path,
dpi = "retina")
ggsave("overall_stability.png",
plot = overall_stability_map,
device = "png",
path = map_path,
dpi = "retina")
Plot stability across species.
# filter for relevant species and asexual reproductive mode
asexual_locs <- loc %>%
mutate(lat_long = str_c(latitude, longitude)) %>%
filter(
reproductive_mode == "asexual",
species == "horridus" |
species == "jucundum" |
species == "hookeri" |
species == "annulata" |
species == "ovobessus" |
species == "huttoni",
!duplicated(lat_long)
) %>%
dplyr::select(longitude, latitude)
# filter for relevant species and sexual reproductive mode
sexual_locs <- loc %>%
mutate(lat_long = str_c(latitude, longitude)) %>%
filter(
reproductive_mode == "sexual",
species == "horridus" |
species == "jucundum" |
species == "hookeri" |
species == "annulata" |
species == "ovobessus" |
species == "huttoni",
!duplicated(lat_long)
) %>%
dplyr::select(longitude, latitude)
# extract preciptitation values and bind into a new dataframe
precip_asexual <-
raster::extract(precip_stability_scaled, asexual_locs) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual <-
raster::extract(precip_stability_scaled, sexual_locs) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df <- bind_rows(precip_asexual, precip_sexual)
# plot precipitation stability
precip_stability_plot <- ggplot(
data = precip_df,
aes(x = reproductive_mode, y = precip_stability_scaled, fill = reproductive_mode)
) +
geom_violin(width = 0.8) +
geom_boxplot(width = 0.1,
color = "gray",
fill = "transparent") +
scale_fill_viridis_d(option = "magma") +
theme_dark()
precip_stability_plot
# extract temperature values and bind into a new data frame
temp_asexual <-
raster::extract(temp_stability_scaled, asexual_locs) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual <-
raster::extract(temp_stability_scaled, sexual_locs) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df <- bind_rows(temp_asexual, temp_sexual)
# plot temperature stability
temp_stability_plot <- ggplot(data = temp_df,
aes(x = reproductive_mode, y = temp_stability_scaled, fill = reproductive_mode)) +
geom_violin(width = 0.8) +
geom_boxplot(width = 0.1,
color = "gray",
fill = "transparent") +
scale_fill_viridis_d(option = "magma") +
theme_dark()
temp_stability_plot
# extract overall stability values and bind into a dataframe
overall_asexual <-
raster::extract(overall_stability_scaled, asexual_locs) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual <-
raster::extract(overall_stability_scaled, sexual_locs) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df <- bind_rows(overall_asexual, overall_sexual)
# plot overall stability
overall_stability_plot <- ggplot(
data = overall_df,
aes(x = reproductive_mode, y = overall_stability_scaled, fill = reproductive_mode)
) +
geom_violin(width = 0.8) +
geom_boxplot(width = 0.1,
color = "gray",
fill = "transparent") +
scale_fill_viridis_d(option = "magma") +
theme_dark()
overall_stability_plot
ggsave("temp_stability_plot.png",
plot = temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
ggsave("precip_stability_plot.png",
plot = precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
ggsave("overall_stability_plot.png",
plot = overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
Environmental space per species
These are PCAs of environmental space for species within genera. Each climate PCA is of localities for a single genus, colored by species. I’m doing this even for genera with one species, so it’s easy to see if certain localities group together.
I’m also conducting Enviromental Niche Factor Analysis to investigate the influence of reproductive mode on niche marginality.
Argosarchus horridus
# conduct pca
summary_list_ahor <- species_pca_fun(data = loc_clim, genus = "argosarchus", species = "horridus")
# plot
ahor_plot <-
plot_clim_pca(summary_list_ahor$loc_clim,
summary_list_ahor$summary_pca,
factor = "reproductive_mode")
ahor_plot
htmlwidgets::saveWidget(ahor_plot,
file.path(interactive_path, "ahor_pca.html"),
selfcontained = TRUE)
#filter localities for the focal species
ahor_loc <- loc %>%
filter(genus == "argosarchus", species == "horridus")
#use sourced plot_locs_leaflet script to plot localities
ahor_map <- plot_locs_leaflet(ahor_loc, "reproductive_mode")
ahor_map
mapview::mapshot(
ahor_map,
url = file.path(interactive_path, "ahor_map.html"),
file = file.path(interactive_path, "ahor_map.pdf")
)
ENFA
Now I’m going to to environmental niche factor analysis between sexual and asexual populations within the species.
#get background env't for the species
ahor_bg_env <- bg_env_crop(ahor_loc,
species = "horridus",
environment = w,
buffer = 0.5)
#enfa for the sexual species
ahor_sexual_enfa <- enfa_calc_fun(locs = ahor_loc,
species = "horridus",
reproductive_mode = "sexual",
mask_raster = ahor_bg_env)
#enfa for the asexual species
ahor_asexual_enfa <- enfa_calc_fun(locs = ahor_loc,
species = "horridus",
reproductive_mode = "asexual",
mask_raster = ahor_bg_env)
#plot the marginality scores
ahor_marginality <- marginality_lollipop(sex_marg = ahor_sexual_enfa$m,
asex_marg = ahor_asexual_enfa$m,
full_species_name = "Argosarchus horridus")
# write scores to csvs
readr::write_csv(
ahor_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ahor_asexual_marginality_score.csv")
)
readr::write_csv(
ahor_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ahor_sexual_marginality_score.csv")
)
ggsave("ahor_marginality_lollipop.png",
plot = ahor_marginality,
device = "png",
path = plot_path,
dpi = "retina")
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. The yellow dot indicates the mean marginality (it’s not the value that is on the lollipop plot, so don’t let that confuse you). 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
ahor_asexual_df <- ahor_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = ahor_asexual_enfa$pr)
readr::write_csv(ahor_asexual_df,
file.path(spread_path, "ahor_asexual_marginality_df.csv"))
ahor_sexual_df <- ahor_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = ahor_sexual_enfa$pr)
readr::write_csv(ahor_sexual_df,
file.path(spread_path, "ahor_sexual_marginality_df.csv"))
#asexual
ahor_enfa_spec_asexual <- enfa_hex_plot(ahor_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ahor_enfa_spec_asexual
ggsave("ahor_enfa_spec_asexual.png",
plot = ahor_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
ahor_enfa_spec_sexual <- enfa_hex_plot(ahor_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ahor_enfa_spec_sexual
ggsave("ahor_enfa_spec_sexual.png",
plot = ahor_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
## asexual
hist(ahor_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
# write to file
png(filename = file.path(plot_path, "ahor_asexual_enfa_hist.png"))
hist(ahor_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
## sexual
hist(ahor_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
# write to file
png(filename = file.path(plot_path, "ahor_sexual_enfa_hist.png"))
hist(ahor_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
ahor_total_pca <- total_climate_pca_plot(bg_env = ahor_bg_env, locs = ahor_loc, genus = "Argosarchus", species = "horridus")
ahor_total_pca
ggsave("ahor_total_pca.png",
plot = ahor_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
ENFA Reduced
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO6, BIO13, BIO14, BIO16
Repeat the analysis with the reduced data set. The background environment is 0.5 degrees, a ballpark dispersal limitation for all stick insect species in this study.
w_ahor <- raster::subset(w, c("bio6", "bio13", "bio14", "bio16"))
#get background env't for the species
ahor_bg_env_subset <- bg_env_crop(ahor_loc,
species = "horridus",
environment = w_ahor,
buffer = 0.5)
#enfa for the sexual species
ahor_sexual_enfa_subset <- enfa_calc_fun(locs = ahor_loc,
species = "horridus",
reproductive_mode = "sexual",
mask_raster = ahor_bg_env_subset)
#enfa for the asexual species
ahor_asexual_enfa_subset <- enfa_calc_fun(locs = ahor_loc,
species = "horridus",
reproductive_mode = "asexual",
mask_raster = ahor_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
ahor_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ahor_subset_asexual_marginality_score.csv")
)
readr::write_csv(
ahor_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ahor_subset_sexual_marginality_score.csv")
)
#plot the marginality scores
ahor_subset_marginality <-
marginality_lollipop(
sex_marg = ahor_sexual_enfa_subset$m,
asex_marg = ahor_asexual_enfa_subset$m,
full_species_name = "Argosarchus horridus"
)
ahor_subset_marginality
ggsave("ahor_subset_marginality.png",
plot = ahor_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with reduced data set
### 1) ENFA scatterplot
#access the relevant values for plotting
ahor_asexual_df_subset <- ahor_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = ahor_asexual_enfa_subset$pr)
readr::write_csv(
ahor_asexual_df_subset,
file.path(spread_path, "ahor_subset_asexual_marginality_df.csv")
)
ahor_sexual_df_subset <- ahor_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = ahor_sexual_enfa_subset$pr)
readr::write_csv(
ahor_sexual_df_subset,
file.path(spread_path, "ahor_subset_sexual_marginality_df.csv")
)
#asexual. Jesus these variable names are getting long
ahor_subset_enfa_spec_asexual <-
enfa_hex_plot(
ahor_asexual_df_subset,
marg = Mar,
spec = Spe1,
repro_mode = "Asexual"
)
ahor_subset_enfa_spec_asexual
ggsave(
"ahor_subset_enfa_spec_asexual.png",
plot = ahor_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina"
)
# sexual
ahor_subset_enfa_spec_sexual <-
enfa_hex_plot(
ahor_sexual_df_subset,
marg = Mar,
spec = Spe1,
repro_mode = "Sexual"
)
ahor_subset_enfa_spec_sexual
ggsave(
"ahor_subset_enfa_spec_sexual.png",
plot = ahor_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina"
)
### 2) ENFA histogram
# asexual
hist(ahor_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ahor_subset_asexual_enfa_hist.png"))
hist(ahor_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(ahor_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ahor_subset_sexual_enfa_hist.png"))
hist(ahor_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
ahor_subset_total_pca <-
total_climate_pca_plot(
bg_env = ahor_bg_env_subset,
locs = ahor_loc,
genus = "Argosarchus",
species = "horridus"
)
ahor_subset_total_pca
ggsave(
"ahor_subset_total_pca.png",
plot = ahor_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina"
)
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(ahor_sexual_enfa, file = file.path(obj_path, "ahor_sexual_enfa.RDS"))
rm(ahor_sexual_enfa)
saveRDS(ahor_asexual_enfa, file = file.path(obj_path, "ahor_asexual_enfa.RDS"))
rm(ahor_asexual_enfa)
saveRDS(ahor_sexual_enfa_subset,
file = file.path(obj_path, "ahor_subset_sexual_enfa.RDS"))
rm(ahor_sexual_enfa_subset)
saveRDS(ahor_asexual_enfa_subset,
file = file.path(obj_path, "ahor_subset_asexual_enfa.RDS"))
rm(ahor_asexual_enfa_subset)
Stability
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
ahor_locs_asexual <- ahor_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
ahor_locs_sexual <- ahor_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_ahor <- raster::extract(precip_stability_scaled, ahor_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_ahor <- raster::extract(precip_stability_scaled, ahor_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_ahor <- bind_rows(precip_asexual_ahor, precip_sexual_ahor)
readr::write_csv(precip_df_ahor,
file.path(spread_path, "ahor_precip_stability_df.csv"))
ahor_precip_stability_plot <- ggplot(data = precip_df_ahor, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ahor_precip_stability_plot
ggsave(
"ahor_precip_stability.png",
plot = ahor_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
temp_asexual_ahor <- raster::extract(temp_stability_scaled, ahor_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_ahor <- raster::extract(temp_stability_scaled, ahor_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_ahor <- bind_rows(temp_asexual_ahor, temp_sexual_ahor)
readr::write_csv(temp_df_ahor,
file.path(spread_path, "ahor_temp_stability_df.csv"))
ahor_temp_stability_plot <- ggplot(data = temp_df_ahor, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ahor_temp_stability_plot
ggsave(
"ahor_temp_stability.png",
plot = ahor_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
overall_asexual_ahor <- raster::extract(overall_stability_scaled, ahor_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_ahor <- raster::extract(overall_stability_scaled, ahor_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_ahor <- bind_rows(overall_asexual_ahor, overall_sexual_ahor)
readr::write_csv(overall_df_ahor,
file.path(spread_path, "ahor_overall_stability_df.csv"))
ahor_overall_stability_plot <- ggplot(data = overall_df_ahor, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ahor_overall_stability_plot
ggsave(
"ahor_overall_stability.png",
plot = ahor_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Seasonality
seas_precip_asexual_ahor <- raster::extract(w$bio15, ahor_locs_asexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_precip_sexual_ahor <- raster::extract(w$bio15, ahor_locs_sexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_precip_df_ahor <- bind_rows(seas_precip_asexual_ahor, seas_precip_sexual_ahor)
readr::write_csv(seas_precip_df_ahor,
file.path(spread_path, "ahor_precip_seasonality_df.csv"))
ahor_precip_seasonality_plot <- ggplot(data = seas_precip_df_ahor, aes(x = reproductive_mode, y = precip_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ahor_precip_seasonality_plot
ggsave(
"ahor_precip_seasonality.png",
plot = ahor_precip_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
seas_temp_asexual_ahor <- raster::extract(w$bio4, ahor_locs_asexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_temp_sexual_ahor <- raster::extract(w$bio4, ahor_locs_sexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_temp_df_ahor <- bind_rows(seas_temp_asexual_ahor, seas_temp_sexual_ahor)
readr::write_csv(seas_temp_df_ahor,
file.path(spread_path, "ahor_temp_seasonality_df.csv"))
ahor_temp_seasonality_plot <- ggplot(data = seas_temp_df_ahor, aes(x = reproductive_mode, y = temp_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ahor_temp_seasonality_plot
ggsave(
"ahor_temp_seasonality.png",
plot = ahor_temp_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Move output
Put all output into species-specific subfolders.
Asteliaphasma jucundum
#pca
summary_list_ajuc <- species_pca_fun(loc_clim,
genus ="asteliaphasma",
species = "jucundum")
#plot
ajuc_plot <- plot_clim_pca(summary_list_ajuc$loc_clim,
summary_list_ajuc$summary_pca,
factor = "reproductive_mode")
ajuc_plot
#if selfcontained = TRUE, you can remove the folder that gets added alongside the plot.
htmlwidgets::saveWidget(ajuc_plot, file.path(interactive_path, "ajuc_pca.html"), selfcontained = TRUE)
#filter localities for the focal species
ajuc_loc <- loc %>%
filter(genus == "asteliaphasma", species == "jucundum")
#use sourced plot_locs_leaflet script to plot localities
ajuc_map <- plot_locs_leaflet(ajuc_loc, "reproductive_mode")
ajuc_map
# save the map
mapview::mapshot(ajuc_map, url = file.path(interactive_path, "ajuc_map.html"), file = file.path(interactive_path, "ajuc_map.pdf"))
ENFA
Now I’m going to to environmental niche factor analysis between sexual and asexual populations within the species.
#get background env't for the species
ajuc_bg_env <- bg_env_crop(aste_loc,
species = "jucundum",
environment = w,
buffer = 0.5)
#enfa for the sexual species
ajuc_sexual_enfa <- enfa_calc_fun(locs = aste_loc,
species = "jucundum",
reproductive_mode = "sexual",
mask_raster = ajuc_bg_env)
#enfa for the asexual species
ajuc_asexual_enfa <- enfa_calc_fun(locs = aste_loc,
species = "jucundum",
reproductive_mode = "asexual",
mask_raster = ajuc_bg_env)
#plot the marginality scores
ajuc_marginality <- marginality_lollipop(sex_marg = ajuc_sexual_enfa$m,
asex_marg = ajuc_asexual_enfa$m,
full_species_name = "Asteliaphasma jucundum")
ajuc_marginality
# write scores to csvs
readr::write_csv(
ajuc_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ajuc_asexual_marginality_score.csv")
)
readr::write_csv(
ajuc_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ajuc_sexual_marginality_score.csv")
)
ggsave("ajuc_marginality_lollipop.png",
plot = ajuc_marginality,
device = "png",
path = plot_path,
dpi = "retina")
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
ajuc_asexual_df <- ajuc_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = ajuc_asexual_enfa$pr)
readr::write_csv(ajuc_asexual_df,
file.path(spread_path, "ajuc_asexual_marginality_df.csv"))
ajuc_sexual_df <- ajuc_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = ajuc_sexual_enfa$pr)
readr::write_csv(ajuc_sexual_df,
file.path(spread_path, "ajuc_sexual_marginality_df.csv"))
#asexual
ajuc_enfa_spec_asexual <- enfa_hex_plot(ajuc_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("ajuc_enfa_spec_asexual.png",
plot = ajuc_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
ajuc_enfa_spec_sexual <- enfa_hex_plot(ajuc_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("ajuc_enfa_spec_sexual.png",
plot = ajuc_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(ajuc_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ajuc_asexual_enfa_hist.png"))
hist(ajuc_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(ajuc_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ajuc_sexual_enfa_hist.png"))
hist(ajuc_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
ajuc_total_pca <- total_climate_pca_plot(bg_env = ajuc_bg_env, locs = aste_loc, genus = "Asteliophasma", species = "jucundum")
ajuc_total_pca
ggsave("ajuc_total_pca.png",
plot = ajuc_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
ENFA Reduced
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO5, BIO6, BIO14, BIO17.
Repeat the analysis with the reduced data set.
w_ajuc <- raster::subset(w, c("bio5", "bio6", "bio14", "bio17"))
#get background env't for the species
ajuc_bg_env_subset <- bg_env_crop(aste_loc,
species = "jucundum",
environment = w_ajuc,
buffer = 0.5)
#enfa for the sexual species
ajuc_sexual_enfa_subset <- enfa_calc_fun(locs = aste_loc,
species = "jucundum",
reproductive_mode = "sexual",
mask_raster = ajuc_bg_env_subset)
#enfa for the asexual species
ajuc_asexual_enfa_subset <- enfa_calc_fun(locs = aste_loc,
species = "jucundum",
reproductive_mode = "asexual",
mask_raster = ajuc_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
ajuc_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ajuc_subset_asexual_marginality_score.csv")
)
readr::write_csv(
ajuc_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ajuc_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
ajuc_subset_marginality <-
marginality_lollipop(
sex_marg = ajuc_sexual_enfa_subset$m,
asex_marg = ajuc_asexual_enfa_subset$m,
full_species_name = "Asteliaphasma jucundum"
)
ajuc_subset_marginality
ggsave("ajuc_subset_marginality.png",
plot = ajuc_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
ajuc_asexual_df_subset <- ajuc_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = ajuc_asexual_enfa_subset$pr)
readr::write_csv(
ajuc_asexual_df_subset,
file.path(spread_path, "ajuc_asexual_df_subset.csv")
)
ajuc_sexual_df_subset <- ajuc_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = ajuc_sexual_enfa_subset$pr)
readr::write_csv(
ajuc_sexual_df_subset,
file.path(spread_path, "ajuc_sexual_df_subset.csv")
)
# asexual
ajuc_subset_enfa_spec_asexual <- enfa_hex_plot(ajuc_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("ajuc_subset_enfa_spec_asexual.png",
plot = ajuc_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
ajuc_subset_enfa_spec_sexual <- enfa_hex_plot(ajuc_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("ajuc_subset_enfa_spec_sexual.png",
plot = ajuc_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(ajuc_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ajuc_subset_asexual_enfa_hist.png"))
hist(ajuc_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(ajuc_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ajuc_subset_sexual_enfa_hist.png"))
hist(ajuc_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
ajuc_subset_total_pca <- total_climate_pca_plot(bg_env = ajuc_bg_env_subset, locs = aste_loc, genus = "Asteliaphasma", species = "jucundum")
ggsave("ajuc_subset_total_pca.png",
plot = ajuc_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(ajuc_sexual_enfa, file = file.path(obj_path, "ajuc_sexual_enfa.RDS"))
rm(ajuc_sexual_enfa)
saveRDS(ajuc_asexual_enfa, file = file.path(obj_path, "ajuc_asexual_enfa.RDS"))
rm(ajuc_asexual_enfa)
saveRDS(ajuc_sexual_enfa_subset,
file = file.path(obj_path, "ajuc_subset_sexual_enfa.RDS"))
rm(ajuc_sexual_enfa_subset)
saveRDS(ajuc_asexual_enfa_subset,
file = file.path(obj_path, "ajuc_subset_asexual_enfa.RDS"))
rm(ajuc_asexual_enfa_subset)
Stability
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
ajuc_locs_asexual <- ajuc_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
ajuc_locs_sexual <- ajuc_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_ajuc <- raster::extract(precip_stability_scaled, aste_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_ajuc <- raster::extract(precip_stability_scaled, aste_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_ajuc <- bind_rows(precip_asexual_ajuc, precip_sexual_ajuc)
readr::write_csv(precip_df_ajuc,
file.path(spread_path, "ajuc_precip_stability_df.csv"))
ajuc_precip_stability_plot <- ggplot(data = precip_df_ajuc, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ajuc_precip_stability_plot
ggsave("ajuc_precip_stability.png",
plot = ajuc_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
temp_asexual_ajuc <- raster::extract(temp_stability_scaled, aste_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_ajuc <- raster::extract(temp_stability_scaled, aste_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_ajuc <- bind_rows(temp_asexual_ajuc, temp_sexual_ajuc)
readr::write_csv(temp_df_ajuc,
file.path(spread_path, "ajuc_temp_stability_df.csv"))
ajuc_temp_stability_plot <- ggplot(data = temp_df_ajuc, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ajuc_temp_stability_plot
ggsave("ajuc_precip_stability.png",
plot = ajuc_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
overall_asexual_ajuc <- raster::extract(overall_stability_scaled, aste_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_ajuc <- raster::extract(overall_stability_scaled, aste_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_ajuc <- bind_rows(overall_asexual_ajuc, overall_sexual_ajuc)
readr::write_csv(overall_df_ajuc,
file.path(spread_path, "ajuc_overall_stability_df.csv"))
ajuc_overall_stability_plot <- ggplot(data = overall_df_ajuc, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ajuc_overall_stability_plot
ggsave("ajuc_overall_stability.png",
plot = ajuc_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
Seasonality
seas_precip_asexual_ajuc <- raster::extract(w$bio15, ajuc_locs_asexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_precip_sexual_ajuc <- raster::extract(w$bio15, ajuc_locs_sexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_precip_df_ajuc <- bind_rows(seas_precip_asexual_ajuc, seas_precip_sexual_ajuc)
readr::write_csv(seas_precip_df_ajuc,
file.path(spread_path, "ajuc_precip_seasonality_df.csv"))
ajuc_precip_seasonality_plot <- ggplot(data = seas_precip_df_ajuc, aes(x = reproductive_mode, y = precip_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ajuc_precip_seasonality_plot
ggsave(
"ajuc_precip_seasonality.png",
plot = ajuc_precip_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
seas_temp_asexual_ajuc <- raster::extract(w$bio4, ajuc_locs_asexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_temp_sexual_ajuc <- raster::extract(w$bio4, ajuc_locs_sexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_temp_df_ajuc <- bind_rows(seas_temp_asexual_ajuc, seas_temp_sexual_ajuc)
readr::write_csv(seas_temp_df_ajuc,
file.path(spread_path, "ajuc_temp_seasonality_df.csv"))
ajuc_temp_seasonality_plot <- ggplot(data = seas_temp_df_ajuc, aes(x = reproductive_mode, y = temp_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ajuc_temp_seasonality_plot
ggsave(
"ajuc_temp_seasonality.png",
plot = ajuc_temp_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Move output
Put all output into species-specific subfolders.
Clitarchus hookeri
summary_list_choo <- species_pca_fun(loc_clim, genus = "clitarchus", species = "hookeri")
choo_plot <- plot_clim_pca(summary_list_choo$loc_clim, summary_list_choo$summary_pca, factor = "reproductive_mode")
choo_plot
htmlwidgets::saveWidget(choo_plot, file.path(interactive_path, "choo_pca.html"), selfcontained = TRUE)
#filter localities for the focal genus
choo_loc <- loc %>%
filter(genus == "clitarchus")
#use sourced plot_locs_leaflet script to plot localities
choo_map <- plot_locs_leaflet(choo_loc, "reproductive_mode")
choo_map
# save the map
mapview::mapshot(
choo_map,
url = file.path(interactive_path, "choo_map.html"),
file = paste0(file.path(interactive_path, "choo_map.pdf"))
)
ENFA
Now I’m going to perform environmental niche factor analysis with sexual and asexual populations within the species.
#get background env't for the species
choo_bg_env <- bg_env_crop(
choo_loc,
species = "hookeri",
environment = w,
buffer = 0.5
)
#enfa for the sexual species
choo_sexual_enfa <- enfa_calc_fun(
locs = choo_loc,
species = "hookeri",
reproductive_mode = "sexual",
mask_raster = choo_bg_env
)
#enfa for the asexual species
choo_asexual_enfa <- enfa_calc_fun(
locs = choo_loc,
species = "hookeri",
reproductive_mode = "asexual",
mask_raster = choo_bg_env
)
# write scores to csvs
readr::write_csv(
choo_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "choo_asexual_marginality_score.csv")
)
readr::write_csv(
choo_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "choo_sexual_marginality_score.csv")
)
#plot the marginality scores
choo_marginality <-
marginality_lollipop(
sex_marg = choo_sexual_enfa$m,
asex_marg = choo_asexual_enfa$m,
full_species_name = "Clitarchus hookeri"
)
choo_marginality
ggsave(
"choo_marginality_lollipop.png",
plot = choo_marginality,
device = "png",
path = plot_path,
dpi = "retina"
)
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
choo_asexual_df <- choo_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = choo_asexual_enfa$pr)
readr::write_csv(choo_asexual_df,
file.path(spread_path, "choo_asexual_marginality_df.csv"))
choo_sexual_df <- choo_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = choo_sexual_enfa$pr)
readr::write_csv(choo_sexual_df,
file.path(spread_path, "choo_sexual_marginality_df.csv"))
# asexual
choo_enfa_spec_asexual <- enfa_hex_plot(choo_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("choo_enfa_spec_asexual.png",
plot = choo_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
choo_enfa_spec_sexual <- enfa_hex_plot(choo_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("choo_enfa_spec_sexual.png",
plot = choo_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(choo_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "choo_asexual_enfa_hist.png"))
hist(choo_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
#sexual
hist(choo_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "choo_sexual_enfa_hist.png"))
hist(choo_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
choo_total_pca <- total_climate_pca_plot(bg_env = choo_bg_env, locs = choo_loc, genus = "Clitarchus", species = "hookeri")
choo_total_pca
ggsave("choo_total_pca.png",
plot = choo_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
ENFA Reduced
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO8, BIO11, BIO15, BIO17.
Repeat the analysis with the reduced data set.
w_choo <- raster::subset(w, c("bio8", "bio11", "bio15", "bio17"))
#get background env't for the species
choo_bg_env_subset <- bg_env_crop(choo_loc,
species = "hookeri",
environment = w_choo,
buffer = 0.5)
#enfa for the sexual species
choo_sexual_enfa_subset <- enfa_calc_fun(locs = choo_loc,
species = "hookeri",
reproductive_mode = "sexual",
mask_raster = choo_bg_env_subset)
#enfa for the asexual species
choo_asexual_enfa_subset <- enfa_calc_fun(locs = choo_loc,
species = "hookeri",
reproductive_mode = "asexual",
mask_raster = choo_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
choo_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "choo_subset_asexual_marginality_score.csv")
)
readr::write_csv(
choo_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "choo_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
choo_subset_marginality <-
marginality_lollipop(
sex_marg = choo_sexual_enfa_subset$m,
asex_marg = choo_asexual_enfa_subset$m,
full_species_name = "Clitarchus hookeri"
)
choo_subset_marginality
ggsave("choo_subset_marginality.png",
plot = choo_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
choo_asexual_df_subset <- choo_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = choo_asexual_enfa_subset$pr)
readr::write_csv(
choo_asexual_df_subset,
file.path(spread_path, "choo_asexual_df_subset.csv")
)
choo_sexual_df_subset <- choo_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = choo_sexual_enfa_subset$pr)
readr::write_csv(
choo_sexual_df_subset,
file.path(spread_path, "choo_sexual_df_subset.csv")
)
# asexual
choo_subset_enfa_spec_asexual <- enfa_hex_plot(choo_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("choo_subset_enfa_spec_asexual.png",
plot = choo_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
choo_subset_enfa_spec_sexual <- enfa_hex_plot(choo_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("choo_subset_enfa_spec_sexual.png",
plot = choo_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(choo_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "choo_subset_asexual_enfa_hist.png"))
hist(choo_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(choo_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "choo_subset_sexual_enfa_hist.png"))
hist(choo_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
choo_subset_total_pca <- total_climate_pca_plot(bg_env = choo_bg_env_subset, locs = choo_loc, genus = "Clitarchus", species = "hookeri")
choo_subset_total_pca
ggsave("choo_subset_total_pca.png",
plot = choo_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(choo_sexual_enfa, file = file.path(obj_path, "choo_sexual_enfa.RDS"))
rm(choo_sexual_enfa)
saveRDS(choo_asexual_enfa, file = file.path(obj_path, "choo_asexual_enfa.RDS"))
rm(choo_asexual_enfa)
saveRDS(choo_sexual_enfa_subset,
file = file.path(obj_path, "choo_subset_sexual_enfa.RDS"))
rm(choo_sexual_enfa_subset)
saveRDS(choo_asexual_enfa_subset,
file = file.path(obj_path, "choo_subset_asexual_enfa.RDS"))
rm(choo_asexual_enfa_subset)
Stability
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
choo_locs_asexual <- choo_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
choo_locs_sexual <- choo_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_choo <- raster::extract(precip_stability_scaled, choo_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_choo <- raster::extract(precip_stability_scaled, choo_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_choo <- bind_rows(precip_asexual_choo, precip_sexual_choo)
readr::write_csv(precip_df_choo,
file.path(spread_path, "choo_precip_stability_df.csv"))
choo_precip_stability_plot <- ggplot(data = precip_df_choo, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
choo_precip_stability_plot
ggsave("choo_precip_stability.png",
plot = choo_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
temp_asexual_choo <- raster::extract(temp_stability_scaled, choo_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_choo <- raster::extract(temp_stability_scaled, choo_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_choo <- bind_rows(temp_asexual_choo, temp_sexual_choo)
readr::write_csv(temp_df_choo,
file.path(spread_path, "choo_temp_stability_df.csv"))
choo_temp_stability_plot <- ggplot(data = temp_df_choo, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
choo_temp_stability_plot
ggsave("choo_precip_stability.png",
plot = choo_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
overall_asexual_choo <- raster::extract(overall_stability_scaled, choo_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_choo <- raster::extract(overall_stability_scaled, choo_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_choo <- bind_rows(overall_asexual_choo, overall_sexual_choo)
readr::write_csv(overall_df_choo,
file.path(spread_path, "choo_overall_stability_df.csv"))
choo_overall_stability_plot <- ggplot(data = overall_df_choo, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
choo_overall_stability_plot
ggsave("choo_overall_stability.png",
plot = choo_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
Seasonality
seas_precip_asexual_choo <- raster::extract(w$bio15, choo_locs_asexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_precip_sexual_choo <- raster::extract(w$bio15, choo_locs_sexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_precip_df_choo <- bind_rows(seas_precip_asexual_choo, seas_precip_sexual_choo)
readr::write_csv(seas_precip_df_choo,
file.path(spread_path, "choo_precip_seasonality_df.csv"))
choo_precip_seasonality_plot <- ggplot(data = seas_precip_df_choo, aes(x = reproductive_mode, y = precip_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
choo_precip_seasonality_plot
ggsave(
"choo_precip_seasonality.png",
plot = choo_precip_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
seas_temp_asexual_choo <- raster::extract(w$bio4, choo_locs_asexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_temp_sexual_choo <- raster::extract(w$bio4, choo_locs_sexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_temp_df_choo <- bind_rows(seas_temp_asexual_choo, seas_temp_sexual_choo)
readr::write_csv(seas_temp_df_choo,
file.path(spread_path, "choo_temp_seasonality_df.csv"))
choo_temp_seasonality_plot <- ggplot(data = seas_temp_df_choo, aes(x = reproductive_mode, y = temp_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
choo_temp_seasonality_plot
ggsave(
"choo_temp_seasonality.png",
plot = choo_temp_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Move output
Put all output into species-specific subfolders.
Niveaphasma annulata
Assuming "longitude" and "latitude" are longitude and latitude, respectively
Importance of components:
PC1 PC2 PC3 PC4 PC5 PC6 PC7 PC8 PC9 PC10
Standard deviation 2.991 2.4512 1.5475 0.94020 0.73312 0.39851 0.21329 0.11142 0.06490 0.04793
Proportion of Variance 0.471 0.3162 0.1260 0.04652 0.02829 0.00836 0.00239 0.00065 0.00022 0.00012
Cumulative Proportion 0.471 0.7872 0.9133 0.95977 0.98806 0.99642 0.99882 0.99947 0.99969 0.99981
PC11 PC12 PC13 PC14 PC15 PC16 PC17 PC18 PC19
Standard deviation 0.03918 0.02539 0.02081 0.01849 0.01623 0.01214 0.01056 0.008283 0.006705
Proportion of Variance 0.00008 0.00003 0.00002 0.00002 0.00001 0.00001 0.00001 0.000000 0.000000
Cumulative Proportion 0.99989 0.99993 0.99995 0.99997 0.99998 0.99999 0.99999 1.000000 1.000000
| bio1 |
0.091 |
0.373 |
0.184 |
| bio10 |
-0.001 |
0.341 |
0.347 |
| bio11 |
0.156 |
0.358 |
0.054 |
| bio12 |
0.297 |
-0.155 |
0.158 |
| bio13 |
0.294 |
-0.152 |
0.172 |
| bio14 |
0.297 |
-0.158 |
0.134 |
| bio15 |
-0.196 |
0.021 |
0.108 |
| bio16 |
0.296 |
-0.144 |
0.177 |
| bio17 |
0.298 |
-0.159 |
0.145 |
| bio18 |
0.300 |
-0.144 |
0.131 |
| bio19 |
0.313 |
-0.119 |
0.116 |
| bio2 |
-0.234 |
-0.233 |
0.273 |
| bio3 |
-0.215 |
-0.206 |
0.340 |
| bio4 |
-0.241 |
-0.238 |
0.232 |
| bio5 |
-0.119 |
0.211 |
0.496 |
| bio6 |
0.177 |
0.345 |
-0.011 |
| bio7 |
-0.234 |
-0.242 |
0.251 |
| bio8 |
-0.171 |
0.255 |
0.194 |
| bio9 |
0.116 |
0.150 |
0.291 |
ENFA
Now I’m going to perform environmental niche factor analysis with sexual and asexual populations within the species.
# get background env't for the species
nann_bg_env <- bg_env_crop(
nann_loc,
species = "annulata",
environment = w,
buffer = 0.5
)
#enfa for the sexual species
nann_sexual_enfa <- enfa_calc_fun(
locs = nann_loc,
species = "annulata",
reproductive_mode = "sexual",
mask_raster = nann_bg_env
)
#enfa for the asexual species
nann_asexual_enfa <- enfa_calc_fun(
locs = nann_loc,
species = "annulata",
reproductive_mode = "asexual",
mask_raster = nann_bg_env
)
# write scores to csvs
readr::write_csv(
nann_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "nann_asexual_marginality_score.csv")
)
readr::write_csv(
nann_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "nann_sexual_marginality_score.csv")
)
#plot the marginality scores
nann_marginality <-
marginality_lollipop(
sex_marg = nann_sexual_enfa$m,
asex_marg = nann_asexual_enfa$m,
full_species_name = "Niveaphasma annulata"
)
nann_marginality
ggsave(
"nann_marginality_lollipop.png",
plot = nann_marginality,
device = "png",
path = plot_path,
dpi = "retina"
)

A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
nann_asexual_df <- nann_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = nann_asexual_enfa$pr)
readr::write_csv(nann_asexual_df,
file.path(spread_path, "nann_asexual_marginality_df.csv"))
nann_sexual_df <- nann_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = nann_sexual_enfa$pr)
readr::write_csv(nann_sexual_df,
file.path(spread_path, "nann_sexual_marginality_df.csv"))
# asexual
nann_enfa_spec_asexual <- enfa_hex_plot(nann_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("nann_enfa_spec_asexual.png",
plot = nann_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
nann_enfa_spec_sexual <- enfa_hex_plot(nann_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("nann_enfa_spec_sexual.png",
plot = nann_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(nann_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
quartz_off_screen
2

quartz_off_screen
2


ENFA Reduced
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO4, BIO8, BIO9, BIO11, BIO15, BIO17
| bio6 |
bio11 |
0.9929211 |
| bio5 |
bio11 |
0.7620957 |
| bio5 |
bio8 |
0.7548208 |
| bio1 |
bio11 |
0.9758130 |
| bio1 |
bio6 |
0.9440310 |
| bio1 |
bio5 |
0.8835979 |
| bio10 |
bio11 |
0.9027414 |
| bio10 |
bio6 |
0.8469003 |
| bio10 |
bio8 |
0.7688311 |
| bio10 |
bio5 |
0.9651367 |
| bio10 |
bio1 |
0.9744331 |
| bio19 |
bio18 |
0.9797213 |
| bio12 |
bio18 |
0.9937581 |
| bio12 |
bio19 |
0.9940107 |
| bio13 |
bio18 |
0.9925247 |
| bio13 |
bio19 |
0.9924016 |
| bio13 |
bio12 |
0.9989788 |
| bio16 |
bio18 |
0.9903177 |
| bio16 |
bio19 |
0.9930871 |
| bio16 |
bio12 |
0.9986837 |
| bio16 |
bio13 |
0.9993091 |
| bio14 |
bio18 |
0.9916471 |
| bio14 |
bio19 |
0.9922512 |
| bio14 |
bio12 |
0.9966334 |
| bio14 |
bio13 |
0.9943050 |
| bio14 |
bio16 |
0.9933774 |
| bio17 |
bio18 |
0.9872752 |
| bio17 |
bio19 |
0.9965362 |
| bio17 |
bio12 |
0.9972430 |
| bio17 |
bio13 |
0.9951214 |
| bio17 |
bio16 |
0.9952717 |
| bio17 |
bio14 |
0.9979879 |
| bio2 |
bio3 |
0.9295684 |
| bio4 |
bio3 |
0.8555918 |
| bio4 |
bio2 |
0.9812381 |
| bio7 |
bio3 |
0.8944362 |
| bio7 |
bio2 |
0.9940598 |
| bio7 |
bio4 |
0.9949823 |

Repeat the analysis with the reduced data set.
w_nann <- raster::subset(w, c("bio4", "bio8", "bio9", "bio11", "bio15", "bio17"))
#get background env't for the species
nann_bg_env_subset <- bg_env_crop(nann_loc,
species = "annulata",
environment = w_nann,
buffer = 0.5)
#enfa for the sexual species
nann_sexual_enfa_subset <- enfa_calc_fun(locs = nann_loc,
species = "annulata",
reproductive_mode = "sexual",
mask_raster = nann_bg_env_subset)
#enfa for the asexual species
nann_asexual_enfa_subset <- enfa_calc_fun(locs = nann_loc,
species = "annulata",
reproductive_mode = "asexual",
mask_raster = nann_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
nann_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "nann_subset_asexual_marginality_score.csv")
)
readr::write_csv(
nann_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "nann_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
nann_subset_marginality <-
marginality_lollipop(
sex_marg = nann_sexual_enfa_subset$m,
asex_marg = nann_asexual_enfa_subset$m,
full_species_name = "Niveaphasma annulata"
)
nann_subset_marginality
ggsave("nann_subset_marginality.png",
plot = nann_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")

Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
nann_asexual_df_subset <- nann_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = nann_asexual_enfa_subset$pr)
readr::write_csv(
nann_asexual_df_subset,
file.path(spread_path, "nann_asexual_df_subset.csv")
)
nann_sexual_df_subset <- nann_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = nann_sexual_enfa_subset$pr)
readr::write_csv(
nann_sexual_df_subset,
file.path(spread_path, "nann_sexual_df_subset.csv")
)
# asexual
nann_subset_enfa_spec_asexual <- enfa_hex_plot(nann_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("nann_subset_enfa_spec_asexual.png",
plot = nann_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
nann_subset_enfa_spec_sexual <- enfa_hex_plot(nann_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("nann_subset_enfa_spec_sexual.png",
plot = nann_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(nann_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
quartz_off_screen
2

quartz_off_screen
2


Stability
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
nann_locs_asexual <- nann_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
nann_locs_sexual <- nann_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_nann <- raster::extract(precip_stability_scaled, nann_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_nann <- raster::extract(precip_stability_scaled, nann_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_nann <- bind_rows(precip_asexual_nann, precip_sexual_nann)
readr::write_csv(precip_df_nann,
file.path(spread_path, "nann_precip_stability_df.csv"))
nann_precip_stability_plot <- ggplot(data = precip_df_nann, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
nann_precip_stability_plot
ggsave("nann_precip_stability.png",
plot = nann_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

temp_asexual_nann <- raster::extract(temp_stability_scaled, nann_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_nann <- raster::extract(temp_stability_scaled, nann_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_nann <- bind_rows(temp_asexual_nann, temp_sexual_nann)
readr::write_csv(temp_df_nann,
file.path(spread_path, "nann_temp_stability_df.csv"))
nann_temp_stability_plot <- ggplot(data = temp_df_nann, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
nann_temp_stability_plot
ggsave("nann_precip_stability.png",
plot = nann_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

overall_asexual_nann <- raster::extract(overall_stability_scaled, nann_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_nann <- raster::extract(overall_stability_scaled, nann_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_nann <- bind_rows(overall_asexual_nann, overall_sexual_nann)
readr::write_csv(overall_df_nann,
file.path(spread_path, "nann_overall_stability_df.csv"))
nann_overall_stability_plot <- ggplot(data = overall_df_nann, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
nann_overall_stability_plot
ggsave("nann_overall_stability.png",
plot = nann_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

Seasonality
seas_precip_asexual_nann <- raster::extract(w$bio15, nann_locs_asexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_precip_sexual_nann <- raster::extract(w$bio15, nann_locs_sexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_precip_df_nann <- bind_rows(seas_precip_asexual_nann, seas_precip_sexual_nann)
readr::write_csv(seas_precip_df_nann,
file.path(spread_path, "nann_precip_seasonality_df.csv"))
nann_precip_seasonality_plot <- ggplot(data = seas_precip_df_nann, aes(x = reproductive_mode, y = precip_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
nann_precip_seasonality_plot
ggsave(
"nann_precip_seasonality.png",
plot = nann_precip_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Saving 7.29 x 4.51 in image

seas_temp_asexual_nann <- raster::extract(w$bio4, nann_locs_asexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_temp_sexual_nann <- raster::extract(w$bio4, nann_locs_sexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_temp_df_nann <- bind_rows(seas_temp_asexual_nann, seas_temp_sexual_nann)
readr::write_csv(seas_temp_df_nann,
file.path(spread_path, "nann_temp_seasonality_df.csv"))
nann_temp_seasonality_plot <- ggplot(data = seas_temp_df_nann, aes(x = reproductive_mode, y = temp_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
nann_temp_seasonality_plot
ggsave(
"nann_temp_seasonality.png",
plot = nann_temp_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Saving 7.29 x 4.51 in image

Move output
Put all output into species-specific subfolders.
nann_out_int_path <- file.path(interactive_path, "niveaphasma_annulata")
nann_out_plot_path <- file.path(plot_path, "niveaphasma_annulata")
nann_out_spread_path <- file.path(spread_path, "niveaphasma_annulata")
nann_out_obj_path <- file.path(obj_path, "niveaphasma_annulata")
# move interactive
move_to_species(in_path = interactive_path,
out_path = nann_out_int_path,
pattern = "nann")
# move plots
move_to_species(in_path = plot_path,
out_path = nann_out_plot_path,
pattern = "nann")
# move spreadsheets
move_to_species(in_path = spread_path,
out_path = nann_out_spread_path,
pattern = "nann")
# move objects
move_to_species(in_path = obj_path,
out_path = nann_out_obj_path,
pattern = "nann")
Tectarchus ovobessus
summary_list_tect_ovo <-
species_pca_fun(loc_clim,
genus = "tectarchus",
species = "ovobessus")
tect_ovo_plot <-
plot_clim_pca(summary_list_tect_ovo$loc_clim,
summary_list_tect_ovo$summary_pca,
factor = "reproductive_mode")
tect_ovo_plot
# save the plot
htmlwidgets::saveWidget(tect_ovo_plot,
file.path(interactive_path, "tect_ovo_pca.html"),
selfcontained = TRUE)
#filter localities for the focal species
tect_ovo_loc <- loc %>%
filter(genus == "tectarchus", species == "ovobessus")
#use sourced plot_locs_leaflet script to plot localities
tect_ovo_map <- plot_locs_leaflet(tect_ovo_loc, "reproductive_mode")
tect_ovo_map
# save the map
mapview::mapshot(
tect_ovo_map,
url = file.path(interactive_path, "tect_ovo_map.html"),
file = file.path(interactive_path, "tect_ovo_map.pdf")
)
ENFA
Now I’m going to perform environmental niche factor analysis with sexual and asexual populations within the species.
# get background env't for the species
tect_ovo_bg_env <- bg_env_crop(
tect_loc,
species = "ovobessus",
environment = w,
buffer = 0.5
)
#enfa for the sexual species
tect_ovo_sexual_enfa <- enfa_calc_fun(
locs = tect_loc,
species = "ovobessus",
reproductive_mode = "sexual",
mask_raster = tect_ovo_bg_env
)
#enfa for the asexual species
tect_ovo_asexual_enfa <- enfa_calc_fun(
locs = tect_loc,
species = "ovobessus",
reproductive_mode = "asexual",
mask_raster = tect_ovo_bg_env
)
# write scores to csvs
readr::write_csv(
tect_ovo_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_ovo_asexual_marginality_score.csv")
)
readr::write_csv(
tect_ovo_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_ovo_sexual_marginality_score.csv")
)
#plot the marginality scores
tect_ovo_marginality <-
marginality_lollipop(
sex_marg = tect_ovo_sexual_enfa$m,
asex_marg = tect_ovo_asexual_enfa$m,
full_species_name = "Tectarchus ovobessus"
)
tect_ovo_marginality
ggsave(
"tect_ovo_marginality_lollipop.png",
plot = tect_ovo_marginality,
device = "png",
path = plot_path,
dpi = "retina"
)
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
tect_ovo_asexual_df <- tect_ovo_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = tect_ovo_asexual_enfa$pr)
readr::write_csv(tect_ovo_asexual_df,
file.path(spread_path, "tect_ovo_asexual_marginality_df.csv"))
tect_ovo_sexual_df <- tect_ovo_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = tect_ovo_sexual_enfa$pr)
readr::write_csv(tect_ovo_sexual_df,
file.path(spread_path, "tect_ovo_sexual_marginality_df.csv"))
# asexual
tect_ovo_enfa_spec_asexual <- enfa_hex_plot(tect_ovo_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("tect_ovo_enfa_spec_asexual.png",
plot = tect_ovo_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
tect_ovo_enfa_spec_sexual <- enfa_hex_plot(tect_ovo_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("tect_ovo_enfa_spec_sexual.png",
plot = tect_ovo_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(tect_ovo_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "tect_ovo_asexual_enfa_hist.png"))
hist(tect_ovo_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
#sexual
hist(tect_ovo_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "tect_ovo_sexual_enfa_hist.png"))
hist(tect_ovo_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
tect_ovo_total_pca <- total_climate_pca_plot(bg_env = tect_ovo_bg_env, locs = tect_loc, genus = "Tectarchus", species = "ovobessus")
tect_ovo_total_pca
ggsave("tect_ovo_total_pca.png",
plot = tect_ovo_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO4, BIO8, BIO11, BIO15, BIO17
ENFA Reduced
Repeat the analysis with the reduced data set.
w_tect_ovo <- raster::subset(w, c("bio4", "bio8", "bio11", "bio15", "bio17"))
#get background env't for the species
tect_ovo_bg_env_subset <- bg_env_crop(tect_loc,
species = "ovobessus",
environment = w_tect_ovo,
buffer = 0.5)
#enfa for the sexual species
tect_ovo_sexual_enfa_subset <- enfa_calc_fun(locs = tect_loc,
species = "ovobessus",
reproductive_mode = "sexual",
mask_raster = tect_ovo_bg_env_subset)
#enfa for the asexual species
tect_ovo_asexual_enfa_subset <- enfa_calc_fun(locs = tect_loc,
species = "ovobessus",
reproductive_mode = "asexual",
mask_raster = tect_ovo_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
tect_ovo_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_ovo_subset_asexual_marginality_score.csv")
)
readr::write_csv(
tect_ovo_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_ovo_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
tect_ovo_subset_marginality <-
marginality_lollipop(
sex_marg = tect_ovo_sexual_enfa_subset$m,
asex_marg = tect_ovo_asexual_enfa_subset$m,
full_species_name = "Tectarchus ovobessus"
)
tect_ovo_subset_marginality
ggsave("tect_ovo_subset_marginality.png",
plot = tect_ovo_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
tect_ovo_asexual_df_subset <- tect_ovo_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = tect_ovo_asexual_enfa_subset$pr)
readr::write_csv(
tect_ovo_asexual_df_subset,
file.path(spread_path, "tect_ovo_asexual_df_subset.csv")
)
tect_ovo_sexual_df_subset <- tect_ovo_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = tect_ovo_sexual_enfa_subset$pr)
readr::write_csv(
tect_ovo_sexual_df_subset,
file.path(spread_path, "tect_ovo_sexual_df_subset.csv")
)
# asexual
tect_ovo_subset_enfa_spec_asexual <- enfa_hex_plot(tect_ovo_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("tect_ovo_subset_enfa_spec_asexual.png",
plot = tect_ovo_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
tect_ovo_subset_enfa_spec_sexual <- enfa_hex_plot(tect_ovo_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("tect_ovo_subset_enfa_spec_sexual.png",
plot = tect_ovo_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(tect_ovo_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "tect_ovo_subset_asexual_enfa_hist.png"))
hist(tect_ovo_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(tect_ovo_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "tect_ovo_subset_sexual_enfa_hist.png"))
hist(tect_ovo_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
tect_ovo_subset_total_pca <- total_climate_pca_plot(bg_env = tect_ovo_bg_env_subset, locs = tect_loc, genus = "Tectarchus", species = "ovobessus")
tect_ovo_subset_total_pca
ggsave("tect_ovo_subset_total_pca.png",
plot = tect_ovo_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(tect_ovo_sexual_enfa, file = file.path(obj_path, "tect_ovo_sexual_enfa.RDS"))
rm(tect_ovo_sexual_enfa)
saveRDS(tect_ovo_asexual_enfa, file = file.path(obj_path, "tect_ovo_asexual_enfa.RDS"))
rm(tect_ovo_asexual_enfa)
saveRDS(tect_ovo_sexual_enfa_subset,
file = file.path(obj_path, "tect_ovo_subset_sexual_enfa.RDS"))
rm(tect_ovo_sexual_enfa_subset)
saveRDS(tect_ovo_asexual_enfa_subset,
file = file.path(obj_path, "tect_ovo_subset_asexual_enfa.RDS"))
rm(tect_ovo_asexual_enfa_subset)
Stability
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
tect_ovo_locs_asexual <- tect_ovo_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
species == "ovobessus",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
tect_ovo_locs_sexual <- tect_ovo_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
species == "ovobessus",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_tect_ovo <- raster::extract(precip_stability_scaled, tect_ovo_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_tect_ovo <- raster::extract(precip_stability_scaled, tect_ovo_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_tect_ovo <- bind_rows(precip_asexual_tect_ovo, precip_sexual_tect_ovo)
readr::write_csv(precip_df_tect_ovo,
file.path(spread_path, "tect_ovo_precip_stability_df.csv"))
tect_ovo_precip_stability_plot <- ggplot(data = precip_df_tect_ovo, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_ovo_precip_stability_plot
ggsave("tect_ovo_precip_stability.png",
plot = tect_ovo_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
temp_asexual_tect_ovo <- raster::extract(temp_stability_scaled, tect_ovo_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_tect_ovo <- raster::extract(temp_stability_scaled, tect_ovo_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_tect_ovo <- bind_rows(temp_asexual_tect_ovo, temp_sexual_tect_ovo)
readr::write_csv(temp_df_tect_ovo,
file.path(spread_path, "tect_ovo_temp_stability_df.csv"))
tect_ovo_temp_stability_plot <- ggplot(data = temp_df_tect_ovo, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_ovo_temp_stability_plot
ggsave("tect_ovo_precip_stability.png",
plot = tect_ovo_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
overall_asexual_tect_ovo <- raster::extract(overall_stability_scaled, tect_ovo_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_tect_ovo <- raster::extract(overall_stability_scaled, tect_ovo_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_tect_ovo <- bind_rows(overall_asexual_tect_ovo, overall_sexual_tect_ovo)
readr::write_csv(overall_df_tect_ovo,
file.path(spread_path, "tect_ovo_overall_stability_df.csv"))
tect_ovo_overall_stability_plot <- ggplot(data = overall_df_tect_ovo, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_ovo_overall_stability_plot
ggsave("tect_ovo_overall_stability.png",
plot = tect_ovo_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
Seasonality
seas_precip_asexual_tect_ovo <- raster::extract(w$bio15, tect_ovo_locs_asexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_precip_sexual_tect_ovo <- raster::extract(w$bio15, tect_ovo_locs_sexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_precip_df_tect_ovo <- bind_rows(seas_precip_asexual_tect_ovo, seas_precip_sexual_tect_ovo)
readr::write_csv(seas_precip_df_tect_ovo,
file.path(spread_path, "tect_ovo_precip_seasonality_df.csv"))
tect_ovo_precip_seasonality_plot <- ggplot(data = seas_precip_df_tect_ovo, aes(x = reproductive_mode, y = precip_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_ovo_precip_seasonality_plot
ggsave(
"tect_ovo_precip_seasonality.png",
plot = tect_ovo_precip_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
seas_temp_asexual_tect_ovo <- raster::extract(w$bio4, tect_ovo_locs_asexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_temp_sexual_tect_ovo <- raster::extract(w$bio4, tect_ovo_locs_sexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_temp_df_tect_ovo <- bind_rows(seas_temp_asexual_tect_ovo, seas_temp_sexual_tect_ovo)
readr::write_csv(seas_temp_df_tect_ovo,
file.path(spread_path, "tect_ovo_temp_seasonality_df.csv"))
tect_ovo_temp_seasonality_plot <- ggplot(data = seas_temp_df_tect_ovo, aes(x = reproductive_mode, y = temp_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_ovo_temp_seasonality_plot
ggsave(
"tect_ovo_temp_seasonality.png",
plot = tect_ovo_temp_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Move output
Put all output into species-specific subfolders.
Tectarchus huttoni
summary_list_tect_hutt <-
species_pca_fun(loc_clim,
genus = "tectarchus",
species = "huttoni")
tect_hutt_plot <-
plot_clim_pca(summary_list_tect_hutt$loc_clim,
summary_list_tect_hutt$summary_pca,
factor = "reproductive_mode")
tect_hutt_plot
# save the plot
htmlwidgets::saveWidget(tect_hutt_plot,
file.path(interactive_path, "tect_hutt_pca.html"),
selfcontained = TRUE)
#filter localities for the focal species
tect_hutt_loc <- loc %>%
filter(genus == "tectarchus", species == "huttoni")
#use sourced plot_locs_leaflet script to plot localities
tect_hutt_map <- plot_locs_leaflet(tect_hutt_loc, "reproductive_mode")
tect_hutt_map
# save the map
mapview::mapshot(
tect_hutt_map,
url = file.path(interactive_path, "tect_hutt_map.html"),
file = file.path(interactive_path, "tect_hutt_map.pdf")
)
ENFA
Now I’m going to perform environmental niche factor analysis with sexual and asexual populations within the species.
# get background env't for the species
tect_hutt_bg_env <- bg_env_crop(
tect_loc,
species = "huttoni",
environment = w,
buffer = 0.5
)
#enfa for the sexual species
tect_hutt_sexual_enfa <- enfa_calc_fun(
locs = tect_loc,
species = "huttoni",
reproductive_mode = "sexual",
mask_raster = tect_hutt_bg_env
)
#enfa for the asexual species
tect_hutt_asexual_enfa <- enfa_calc_fun(
locs = tect_loc,
species = "huttoni",
reproductive_mode = "asexual",
mask_raster = tect_hutt_bg_env
)
# write scores to csvs
readr::write_csv(
tect_hutt_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_hutt_asexual_marginality_score.csv")
)
readr::write_csv(
tect_hutt_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_hutt_sexual_marginality_score.csv")
)
#plot the marginality scores
tect_hutt_marginality <-
marginality_lollipop(
sex_marg = tect_hutt_sexual_enfa$m,
asex_marg = tect_hutt_asexual_enfa$m,
full_species_name = "Tectarchus huttoni"
)
tect_hutt_marginality
ggsave(
"tect_hutt_marginality_lollipop.png",
plot = tect_hutt_marginality,
device = "png",
path = plot_path,
dpi = "retina"
)
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
tect_hutt_asexual_df <- tect_hutt_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = tect_hutt_asexual_enfa$pr)
readr::write_csv(tect_hutt_asexual_df,
file.path(spread_path, "tect_hutt_asexual_marginality_df.csv"))
tect_hutt_sexual_df <- tect_hutt_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = tect_hutt_sexual_enfa$pr)
readr::write_csv(tect_hutt_sexual_df,
file.path(spread_path, "tect_hutt_sexual_marginality_df.csv"))
# asexual
tect_hutt_enfa_spec_asexual <- enfa_hex_plot(tect_hutt_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("tect_hutt_enfa_spec_asexual.png",
plot = tect_hutt_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
tect_hutt_enfa_spec_sexual <- enfa_hex_plot(tect_hutt_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("tect_hutt_enfa_spec_sexual.png",
plot = tect_hutt_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(tect_hutt_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "tect_hutt_asexual_enfa_hist.png"))
hist(tect_hutt_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
#sexual
hist(tect_hutt_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "tect_hutt_sexual_enfa_hist.png"))
hist(tect_hutt_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
tect_hutt_total_pca <- total_climate_pca_plot(bg_env = tect_hutt_bg_env, locs = tect_loc, genus = "Tectarchus", species = "huttoni")
tect_hutt_total_pca
ggsave("tect_hutt_total_pca.png",
plot = tect_hutt_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
ENFA Reduced
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO4, BIO8, BIO11, BIO15, BIO17
Repeat the analysis with the reduced data set.
w_tect_hutt <- raster::subset(w, c("bio4", "bio8", "bio11", "bio15", "bio17"))
#get background env't for the species
tect_hutt_bg_env_subset <- bg_env_crop(tect_loc,
species = "huttoni",
environment = w_tect_hutt,
buffer = 0.5)
#enfa for the sexual species
tect_hutt_sexual_enfa_subset <- enfa_calc_fun(locs = tect_loc,
species = "huttoni",
reproductive_mode = "sexual",
mask_raster = tect_hutt_bg_env_subset)
#enfa for the asexual species
tect_hutt_asexual_enfa_subset <- enfa_calc_fun(locs = tect_loc,
species = "huttoni",
reproductive_mode = "asexual",
mask_raster = tect_hutt_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
tect_hutt_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_hutt_subset_asexual_marginality_score.csv")
)
readr::write_csv(
tect_hutt_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_hutt_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
tect_hutt_subset_marginality <-
marginality_lollipop(
sex_marg = tect_hutt_sexual_enfa_subset$m,
asex_marg = tect_hutt_asexual_enfa_subset$m,
full_species_name = "Tectarchus huttoni"
)
tect_hutt_subset_marginality
ggsave("tect_hutt_subset_marginality.png",
plot = tect_hutt_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
tect_hutt_asexual_df_subset <- tect_hutt_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = tect_hutt_asexual_enfa_subset$pr)
readr::write_csv(
tect_hutt_asexual_df_subset,
file.path(spread_path, "tect_hutt_asexual_df_subset.csv")
)
tect_hutt_sexual_df_subset <- tect_hutt_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = tect_hutt_sexual_enfa_subset$pr)
readr::write_csv(
tect_hutt_sexual_df_subset,
file.path(spread_path, "tect_hutt_sexual_df_subset.csv")
)
# asexual
tect_hutt_subset_enfa_spec_asexual <- enfa_hex_plot(tect_hutt_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("tect_hutt_subset_enfa_spec_asexual.png",
plot = tect_hutt_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
tect_hutt_subset_enfa_spec_sexual <- enfa_hex_plot(tect_hutt_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("tect_hutt_subset_enfa_spec_sexual.png",
plot = tect_hutt_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(tect_hutt_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "tect_hutt_subset_asexual_enfa_hist.png"))
hist(tect_hutt_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(tect_hutt_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "tect_hutt_subset_sexual_enfa_hist.png"))
hist(tect_hutt_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
tect_hutt_subset_total_pca <- total_climate_pca_plot(bg_env = tect_hutt_bg_env_subset, locs = tect_loc, genus = "Tectarchus", species = "huttoni")
tect_hutt_subset_total_pca
ggsave("tect_hutt_subset_total_pca.png",
plot = tect_hutt_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(tect_hutt_sexual_enfa, file = file.path(obj_path, "tect_hutt_sexual_enfa.RDS"))
rm(tect_hutt_sexual_enfa)
saveRDS(tect_hutt_asexual_enfa, file = file.path(obj_path, "tect_hutt_asexual_enfa.RDS"))
rm(tect_hutt_asexual_enfa)
saveRDS(tect_hutt_sexual_enfa_subset,
file = file.path(obj_path, "tect_hutt_subset_sexual_enfa.RDS"))
rm(tect_hutt_sexual_enfa_subset)
saveRDS(tect_hutt_asexual_enfa_subset,
file = file.path(obj_path, "tect_hutt_subset_asexual_enfa.RDS"))
rm(tect_hutt_asexual_enfa_subset)
Stabilityy
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
tect_hutt_locs_asexual <- tect_hutt_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
species == "huttoni",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
tect_hutt_locs_sexual <- tect_hutt_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
species == "huttoni",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_tect_hutt <- raster::extract(precip_stability_scaled, tect_hutt_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_tect_hutt <- raster::extract(precip_stability_scaled, tect_hutt_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_tect_hutt <- bind_rows(precip_asexual_tect_hutt, precip_sexual_tect_hutt)
readr::write_csv(precip_df_tect_hutt,
file.path(spread_path, "tect_hutt_precip_stability_df.csv"))
tect_hutt_precip_stability_plot <- ggplot(data = precip_df_tect_hutt, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_hutt_precip_stability_plot
ggsave("tect_hutt_precip_stability.png",
plot = tect_hutt_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
temp_asexual_tect_hutt <- raster::extract(temp_stability_scaled, tect_hutt_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_tect_hutt <- raster::extract(temp_stability_scaled, tect_hutt_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_tect_hutt <- bind_rows(temp_asexual_tect_hutt, temp_sexual_tect_hutt)
readr::write_csv(temp_df_tect_hutt,
file.path(spread_path, "tect_hutt_temp_stability_df.csv"))
tect_hutt_temp_stability_plot <- ggplot(data = temp_df_tect_hutt, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_hutt_temp_stability_plot
ggsave("tect_hutt_precip_stability.png",
plot = tect_hutt_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
overall_asexual_tect_hutt <- raster::extract(overall_stability_scaled, tect_hutt_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_tect_hutt <- raster::extract(overall_stability_scaled, tect_hutt_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_tect_hutt <- bind_rows(overall_asexual_tect_hutt, overall_sexual_tect_hutt)
readr::write_csv(overall_df_tect_hutt,
file.path(spread_path, "tect_hutt_overall_stability_df.csv"))
tect_hutt_overall_stability_plot <- ggplot(data = overall_df_tect_hutt, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_hutt_overall_stability_plot
ggsave("tect_hutt_overall_stability.png",
plot = tect_hutt_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
Seasonality
seas_precip_asexual_tect_hutt <- raster::extract(w$bio15, tect_hutt_locs_asexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_precip_sexual_tect_hutt <- raster::extract(w$bio15, tect_hutt_locs_sexual) %>%
enframe(name = NULL, value = "precip_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_precip_df_tect_hutt <- bind_rows(seas_precip_asexual_tect_hutt, seas_precip_sexual_tect_hutt)
readr::write_csv(seas_precip_df_tect_hutt,
file.path(spread_path, "tect_hutt_precip_seasonality_df.csv"))
tect_hutt_precip_seasonality_plot <- ggplot(data = seas_precip_df_tect_hutt, aes(x = reproductive_mode, y = precip_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_hutt_precip_seasonality_plot
ggsave(
"tect_hutt_precip_seasonality.png",
plot = tect_hutt_precip_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
seas_temp_asexual_tect_hutt <- raster::extract(w$bio4, tect_hutt_locs_asexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "asexual")
seas_temp_sexual_tect_hutt <- raster::extract(w$bio4, tect_hutt_locs_sexual) %>%
enframe(name = NULL, value = "temp_seasonality") %>%
mutate(reproductive_mode = "sexual")
seas_temp_df_tect_hutt <- bind_rows(seas_temp_asexual_tect_hutt, seas_temp_sexual_tect_hutt)
readr::write_csv(seas_temp_df_tect_hutt,
file.path(spread_path, "tect_hutt_temp_seasonality_df.csv"))
tect_hutt_temp_seasonality_plot <- ggplot(data = seas_temp_df_tect_hutt, aes(x = reproductive_mode, y = temp_seasonality, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_hutt_temp_seasonality_plot
ggsave(
"tect_hutt_temp_seasonality.png",
plot = tect_hutt_temp_seasonality_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Move output
Put all output into species-specific subfolders.
Convenience scripts
These scripts aren’t crucial for reproducing this analysis, but were helpful for various reasons. Some of these have hard-coded paths and such, so no guarantees for use right out of the box.
This was a script I used to take full chelsa files, crop them to New Zealand extent, and write them to a file with my personal computer. I don’t have much memory, so unzipping to a temporary directory, then deleting the directory to free up space for the large files worked.
## get chelsa data
chelsa_folder <- "/Users/connorfrench/Dropbox/Old_Mac/climate-data/chelsa_30s_bio"
zip_files <- list.files(chelsa_folder, full.names = TRUE)
# using the Unarchiver commandline tools for Mac to unzip the 7zip chelsa layers. Regular unzip() does not work with 7z zipped files
for (file in zip_files) {
# set temp directory
tempd <- tempdir()
system(paste("unar", file, "-o", tempd))
r <- raster(list.files(tempd, pattern = "*.tif", full.names = TRUE)) %>%
crop(extent(166, 179, -48, -34))
writeRaster(r, filename = paste0("~/Desktop/", list.files(tempd, pattern = "*.asc")), format = "ascii")
unlink(tempd, recursive = TRUE)
}
LS0tCnRpdGxlOiAiU3RpY2sgSW5zZWN0IENsaW1hdGUgUENBIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogZmxhdGx5CiAgICBoaWdobGlnaHQ6IHRhbmdvCi0tLQoKIyMgRGF0YQoKU29ycnkgZm9yIGFsbCBvZiB0aGUgcGFja2FnZXMuIFRoZXkgZ3JldyBhbmQgZ3JldyBhbmQgZ3JldywgYW5kIEkgZG9uJ3Qgd2FudCB0byByZWZhY3RvciBldmVyeXRoaW5nIHRvIHJlZHVjZSB0aGUgZGVwZW5kZW5jaWVzLgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShyYXN0ZXIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShzZikKI1JTdG9vbGJveCBoYXMgc29tZSBkZXBlbmRlbmNpZXMgbGlrZSBvcGVuTVAgdGhhdCBjYW4gYmUgZGlmZmljdWx0IHRvIGNvbXBpbGUgb24gYSBNYWMgKG5lZWRlZCBmb3IgdGhlIGRlcGVuZGVudCBwYWNrYWdlICJjYXJldCIpLiBJZiB5b3UgaGF2ZSBIaWdoIFNpZXJyYSBPUyBvciBuZXdlciwgc2VhcmNoIGZvciBpbnN0cnVjdGlvbnMgc3BlY2lmaWMgdG8geW91ciBPUy0gaXQncyBhIGxvdCBlYXNpZXIgdGhhbiBvbGRlciBPUydzLgpsaWJyYXJ5KFJTdG9vbGJveCkKbGlicmFyeShsZWFmbGV0KQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnZGF0YSkKbGlicmFyeShCU0RBKQpsaWJyYXJ5KGFkZTQpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkocm5hdHVyYWxlYXJ0aCkKbGlicmFyeShhZGVoYWJpdGF0SFMpCmxpYnJhcnkoY2xpbWF0ZVN0YWJpbGl0eSkKbGlicmFyeShodG1sd2lkZ2V0cykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dzcGF0aWFsKQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkobWFwdmlldykKbGlicmFyeShmcykKCiMgc291cmNlIGxvY2FsaXR5IHBsb3R0aW5nIGZ1bmN0aW9uCnNvdXJjZShoZXJlOjpoZXJlKCJSIiwgInBsb3RfbGVhZmxldF9mdW5jdGlvbi5SIikpIAoKIyBzb3VyY2UgY2xpbWF0ZSBwY2EgcGxvdHRpbmcgZnVuY3Rpb24Kc291cmNlKGhlcmU6OmhlcmUoIlIiLCAicGxvdF9jbGltYXRlX3BjYV9mdW5jdGlvbi5SIikpIAoKIyBzb3VyY2Ugc3BlY2llcyBwY2EgcGxvdHRpbmcgZnVuY3Rpb24Kc291cmNlKGhlcmU6OmhlcmUoIlIiLCAic3BlY2llc19wY2FfZnVuY3Rpb24uUiIpKSAKCiMgc291cmNlIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhIG1pbmltdW0gY29udmV4IHBvbHlnb24gYXJvdW5kIHBvaW50cwpzb3VyY2UoaGVyZTo6aGVyZSgiUiIsICJtaW5fY29udmV4X3BvbHkuUiIpKSAKCgpzb3VyY2UoaGVyZTo6aGVyZSgiUiIsICJlbmZhX2NhbGNfZnVuY3Rpb24uUiIpKQpzb3VyY2UoaGVyZTo6aGVyZSgiUiIsICJtYXJnaW5hbGl0eV9sb2xsaXBvcF9wbG90LlIiKSkKc291cmNlKGhlcmU6OmhlcmUoIlIiLCAicHJlc2VuY2VfYWJzZW5jZV9yYXN0ZXJfZnVuY3Rpb24uUiIpKQpzb3VyY2UoaGVyZTo6aGVyZSgiUiIsICJjcm9wX2JhY2tncm91bmRfZW52X2Z1bmN0aW9uLlIiKSkKc291cmNlKGhlcmU6OmhlcmUoIlIiLCAiZW5mYV9oZXhfcGxvdC5SIikpCnNvdXJjZShoZXJlOjpoZXJlKCJSIiwgInRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QuUiIpKQpzb3VyY2UoaGVyZTo6aGVyZSgiUiIsICJyYXN0ZXJfY29ycmVsYXRpb25fZnVuY3Rpb24uUiIpKQpzb3VyY2UoaGVyZTo6aGVyZSgiUiIsICJtb3ZlX3RvX3NwZWNpZXMuUiIpKQpgYGAKCgpDcmVhdGUgc3ViZGlyZWN0b3JpZXMgKGlmIG5lZWRlZCkgYW5kIGVzdGFibGlzaCBwYXRocy4KYGBge3J9CiMgZnVuY3Rpb24gdG8gY2hlY2sgaWYgc3ViZm9sZGVyIGV4aXN0cy4gSWYgbm90LCBtYWtlIGl0CmNyZWF0ZV9kaXIgPC0gZnVuY3Rpb24ob3V0X3BhdGgpIHsKICBpZiAoIWRpci5leGlzdHMob3V0X3BhdGgpKSB7CiAgICBkaXIuY3JlYXRlKG91dF9wYXRoKQogIH0gZWxzZQogICAgcHJpbnQoIkRpcmVjdG9yeSBhbHJlYWR5IHRoZXJlLiIpCn0KCiMgcGF0aCBmb3IgaW50ZXJhY3RpdmUgcGxvdHMsIG1hcHMsIGV0Yy4gb3V0cHV0CmludGVyYWN0aXZlX3BhdGggPC0gaGVyZTo6aGVyZSgib3V0cHV0IiwgImludGVyYWN0aXZlX3Bsb3RzIikKCmNyZWF0ZV9kaXIoaW50ZXJhY3RpdmVfcGF0aCkKCiMgY2xpbWF0ZSBkYXRhCmNsaW1hdGVfcGF0aCA8LSAKICBoZXJlOjpoZXJlKCJkYXRhIiwKICAgICAgICAgICAgICJjbGltYXRlIikKCmNyZWF0ZV9kaXIoY2xpbWF0ZV9wYXRoKQoKIyB0ZW1wZXJhdHVyZSBjbGltYXRlIGRhdGEKdGVtcF9wYXRoIDwtCiAgaGVyZTo6aGVyZSgiZGF0YSIsCiAgICAgICAiY2xpbWF0ZSIsCiAgICAgICAicGFsZW9jbGltX2xhdGVfcGxlaXN0b2NlbmUiLAogICAgICAgInRlbXBlcmF0dXJlIikKCmNyZWF0ZV9kaXIodGVtcF9wYXRoKQoKIyBwcmVjaXBpdGF0aW9uIGNsaW1hdGUgZGF0YQpwcmVjaXBfcGF0aCA8LQogIGhlcmU6OmhlcmUoImRhdGEiLAogICAgICAgImNsaW1hdGUiLAogICAgICAgInBhbGVvY2xpbV9sYXRlX3BsZWlzdG9jZW5lIiwKICAgICAgICJwcmVjaXBpdGF0aW9uIikKCmNyZWF0ZV9kaXIocHJlY2lwX3BhdGgpCgojIHJhc3RlciBvdXRwdXQKcmFzdGVyX3BhdGggPC0gCiAgaGVyZTo6aGVyZSgib3V0cHV0IiwKICAgICAgICAgICAgICJyYXN0ZXJzIikKCmNyZWF0ZV9kaXIocmFzdGVyX3BhdGgpCgojIG1hcCAobm9uLWludGVyYWN0aXZlKSBvdXRwdXQKbWFwX3BhdGggPC0gaGVyZTo6aGVyZSgib3V0cHV0IiwgIm1hcHMiKQoKY3JlYXRlX2RpcihtYXBfcGF0aCkKCiMgcGxvdCAobm9uLWludGVyYWN0aXZlKSBvdXRwdXQKcGxvdF9wYXRoIDwtIGhlcmU6OmhlcmUoIm91dHB1dCIsICJwbG90cyIpCgpjcmVhdGVfZGlyKHBsb3RfcGF0aCkKCiMgc3ByZWFkc2hlZXQgb3V0cHV0CnNwcmVhZF9wYXRoIDwtIGhlcmU6OmhlcmUoIm91dHB1dCIsICJzcHJlYWRzaGVldHMiKQoKY3JlYXRlX2RpcihzcHJlYWRfcGF0aCkKCiMgUiBvYmplY3QgKGUuZy4gLlJEUyBmaWxlcykgb3V0cHV0Cm9ial9wYXRoIDwtIGhlcmU6OmhlcmUoIm91dHB1dCIsICJvYmplY3RzIikKCmNyZWF0ZV9kaXIob2JqX3BhdGgpCgpgYGAKCgoKUmVhZCBpbiB0aGUgc3ByZWFkc2hlZXQgYW5kIHRha2UgYSBsb29rIGF0IHRoZSBkYXRhLgoKYGBge3J9CiMgZGF0YSBwYXRoCmxvY19wYXRoIDwtIGhlcmU6OmhlcmUoImRhdGEiLCAiYWxsIHNwZWNpZXMgTmV3XzYtMTQtMTkueGxzeCIpCgojIHNwZWNpZXMgbGlzdCAKc3BlY2llc19saXN0IDwtIGMoImhvcnJpZHVzIiwgCiAgICAgICAgICAgICAgICAgICJob29rZXJpIiwKICAgICAgICAgICAgICAgICAgImFubnVsYXRhIiwKICAgICAgICAgICAgICAgICAgIm92b2Jlc3N1cyIsCiAgICAgICAgICAgICAgICAgICJodXR0b25pIiwKICAgICAgICAgICAgICAgICAgImp1Y3VuZHVtIikKCiMjIyByZWFkIGluIHNwcmVhZHNoZWV0CmxvYyA8LSByZWFkX3hsc3gobG9jX3BhdGgpICU+JQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9IGFzLmZhY3RvcihyZXByb2R1Y3RpdmVfbW9kZSkpICU+JSAKICBmaWx0ZXIoc3BlY2llcyAlaW4lIHNwZWNpZXNfbGlzdCkKCiNnZXQgdGhlIG51bWJlciBvZiBpbmRpdmlkdWFscywgYW5kIHRoZSBzZXh1YWxpdHkgY291bnRzIHBlciBzcGVjaWVzCmNvdW50X3JlcHJvX21vZGUgPC0gbG9jICU+JSAKICBncm91cF9ieShnZW51cywgc3BlY2llcywgcmVwcm9kdWN0aXZlX21vZGUpICU+JSAKICBkcGx5cjo6Y291bnQoKSAlPiUgCiAgbXV0YXRlKGdlbnVzX3NwZWNpZXMgPSBzdHJfYyhnZW51cywgc3BlY2llcywgc2VwID0gIl8iKSwKICAgICAgICAgZ2VudXNfc3BlY2llcyA9IHN0cl9yZXBsYWNlX2FsbChnZW51c19zcGVjaWVzLCAiICIsICJfIiksCiAgICAgICAgIGdlbnVzX3NwZWNpZXMgPSBzdHJfcmVwbGFjZV9hbGwoZ2VudXNfc3BlY2llcywgIlxcLiIsICIiKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKGdlbnVzX3NwZWNpZXMgPSBmY3RfcmVvcmRlcihnZW51c19zcGVjaWVzLCBuLCBzdW0pKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZ2VudXNfc3BlY2llcywgeSA9IG4sIGZpbGwgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2NvbCgpICsKICBjb29yZF9mbGlwKCkgKyAKICB0aGVtZV9taW5pbWFsKCkKCmNvdW50X3JlcHJvX21vZGUKYGBgCgojIyBNYXAKUGxvdCBhIGxlYWZsZXQgbWFwIG9mIHRoZSBsb2NhbGl0aWVzLiBUaGUgbGVhZmxldCBtYXAgaXMgaW50ZXJhY3RpdmUuIFlvdSBjYW4gY2xpY2sgb24gdGhlIGxvY2FsaXRpZXMgYW5kIGEgZmxhZyB3aXRoIHNvbWUgbWV0YWRhdGEgd2lsbCBwb3AgdXAhIAoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI21ha2UgbG9jYWxpdHkgc2hhcGUgZmlsZSBhbmQgYXNzaWduIFdHUyBjb29yZCBzeXN0ZW0KY29vcmRfcG9pbnRzIDwtIHN0X2FzX3NmKGxvYywgY29vcmRzID0gYygibG9uZ2l0dWRlIiwgImxhdGl0dWRlIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgY3JzID0gNDMyNiwgYWdyID0gImNvbnN0YW50IikKCiN1c2Ugc291cmNlZCBwbG90X2xvY3NfbGVhZmxldCBzY3JpcHQgdG8gcGxvdCBsb2NhbGl0aWVzCmFsbF9wbG90IDwtIHBsb3RfbG9jc19sZWFmbGV0KGxvYywgInJlcHJvZHVjdGl2ZV9tb2RlIikKCmFsbF9wbG90CgojIHNhdmUgdGhlIG1hcAptYXB2aWV3OjptYXBzaG90KAogIGFsbF9wbG90LAogIHVybCA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiYWxsX3NwZWNpZXNfbWFwLmh0bWwiKSwKICBmaWxlID0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhbGxfc3BlY2llc19tYXAucGRmIikKKQpgYGAKCiMjIFBDQS1HZW5lcmEgey50YWJzZXR9CgojIyMgQ2xpbWF0ZSBEYXRhClJlYWQgaW4gdGhlIGJpb2NsaW0gbGF5ZXJzIGZvciBhbmFseXNpcy4gSSdtIHVzaW5nIGFsbCAxOSBmb3IgdGhpcyBwcmVsaW1pbmFyeSBleHBsb3JhdGlvbi4gSSdtIHVzaW5nIENIRUxTQSB2MS4yIGRhdGEgZG93bmxvYWRlZCBmcm9tIFt0aGVpciB3ZWJzaXRlXShodHRwOi8vY2hlbHNhLWNsaW1hdGUub3JnL2Rvd25sb2Fkcy8pLiBQbG90dGluZyB0aGUgZmlyc3QgdGVtcGVyYXR1cmUgbGF5ZXIgdG8gdGFrZSBhIGxvb2sgYXQgdGhlIGRhdGEuCmBgYHtyIGNhY2hlPVRSVUV9CmNsaW1fZmlsZXMgPC0gaGVyZTo6aGVyZSgiZGF0YSIsICJjbGltYXRlIikgJT4lIAogIGxpc3QuZmlsZXMocGF0dGVybiA9ICIudGlmIiwgZnVsbC5uYW1lcyA9IFRSVUUpCgp3IDwtIHN0YWNrKGNsaW1fZmlsZXMpCgojc2hvcnRlbiB0aGUgbmFtZXMgb2YgdGhlIGJpb2NsaW1zCm5hbWVzKHcpIDwtIHBhc3RlMCgKICBzdHJpbmdyOjpzdHJfZXh0cmFjdChuYW1lcyh3KSwgImJpbyIpLCAKICBzdHJpbmdyOjpzdHJfZXh0cmFjdChuYW1lcyh3KSwgIlxcZCskIikKICApCgoKZ2dwbG90KCkgKwogIGdnc3BhdGlhbDo6bGF5ZXJfc3BhdGlhbChkYXRhID0gd1tbMV1dKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MobmEudmFsdWUgPSAidHJhbnNwYXJlbnQiKSArCiAgbGFicyhmaWxsID0gIkFubnVhbCBBdmcgVGVtcCAoQyoxMCkiKSArCiAgdGhlbWVfbWluaW1hbCgpCiAgCmBgYAoKCiMjIyBQQ0EgYnkgbG9jYWxpdHkKVGhpcyBpcyBhIFBDQSBvZiB0aGUgY2xpbWF0ZSBkYXRhIGV4dHJhY3RlZCBmb3IgZWFjaCBsb2NhbGl0eSwgcmF0aGVyIHRoYW4gYSBQQ0Egb2YgdGhlIHRvdGFsIGNsaW1hdGUgc3BhY2UuIFRoaXMgZ2l2ZXMgdXMgYSBnZW5lcmFsIGlkZWEgb2YgZGlmZmVyZW5jZXMgaW4gZW52aXJvbm1lbnRhbCBuaWNoZS4KClJ1biB0aGUgcGNhIGFuZCBjaGVjayBvdXQgdmFyaWFibGUgbG9hZGluZ3MgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGNvbXBvbmVudHMuCgpgYGB7ciBjYWNoZT1UUlVFfQojZXh0cmFjdCBkYXRhIGZyb20gY2hlbHNhIGZvciBlYWNoIGxvY2FsaXR5LiBNYWtpbmcgdGhpcyBpbnRvIGEgZGF0YSBmcmFtZSB3aXRoIGNvbHVtbnMgbGFiZWxlZCBzbyB0aGUgcm93IGxhYmVsaW5nIGxpbmVzIHVwIGFmdGVyIEkgcmVtb3ZlIHRoZSBOQXMuCiNleHRyYWN0IGRhdGEgZnJvbSB3b3JsZGNsaW0gZm9yIGVhY2ggbG9jYWxpdHkuCmNvb3JkcyA8LSBkYXRhLmZyYW1lKGxhdGl0dWRlID0gbG9jJGxvbmdpdHVkZSwgbG9uZ2l0dWRlID0gbG9jJGxhdGl0dWRlKQoKbG9jX2NsaW0gPC0KICBkcGx5cjo6YmluZF9jb2xzKGxvYywgcmFzdGVyOjpleHRyYWN0KHcsIGNvb3JkcywgbWV0aG9kID0gInNpbXBsZSIsIGRmID0gVFJVRSkpICU+JQogIGRyb3BfbmEoYmlvMSkgJT4lCiAgZHBseXI6OnNlbGVjdCgtSUQpCgojbWFrZSBhIG1hdHJpeCBvZiBvbmx5IGJpb2NsaW0gdmFsdWVzCmNsaW1fbWF0IDwtIGxvY19jbGltWyxncmVwKCJiaW8iLCBuYW1lcyhsb2NfY2xpbSkpXSAlPiUgYXMubWF0cml4KCkKCiNydW4gcGNhIG9uIGNsaW1hdGUgdmFyaWFibGVzCmNsaW1fcGNhIDwtIHByY29tcChjbGltX21hdCwgc2NhbGUgPSBUUlVFKQpzdW1tYXJ5X3BjYSA8LSBzdW1tYXJ5KGNsaW1fcGNhKSAjY2hlY2sgb3V0IHRoZSBjb21wb25lbnRzCgojcGxvdCB0YWJsZXMKc3VtbWFyeV9wY2EKa25pdHI6OmthYmxlKHJvdW5kKGNsaW1fcGNhJHJvdGF0aW9uWywxOjNdLDMpKSAjVGFibGUgb2YgbG9hZGluZyBzY29yZXMgZm9yIHRoZSBmaXJzdCAzIFBDcy4KCmBgYAoKVHdvIHBsb3RzOiBPbmUgcGxvdCBvZiB0aGUgUENBIGNvbG9yZWQgYWNjb3JkaW5nIHRvIGdlbnVzLCB3aXRoIGNvbnZleCBodWxscyBzdXJyb3VuZGluZyB0aGUgZ2VuZXJhLiBJdCBsb29rcyBsaWtlIHRoaXMgcmVmbGVjdHMgYSBsYXRpdHVkaW5hbCBncmFkaWVudCBpbiB0ZW1wZXJhdHVyZSEgWW91IGNhbiBpbnRlcmFjdCB3aXRoIHRoZSBQQ0EgcGxvdCBieSBjbGlja2luZyBvbiBwb2ludHMgdG8gdmlldyBhc3NvY2lhdGVkIG1ldGFkYXRhLiBZb3UgY2FuIGlzb2xhdGUgdGhlIGdlbnVzIHlvdSB3YW50IHRvIHZpZXcgYnkgZG91YmxlIGNsaWNraW5nIHRoZSBnZW51cyBpbiB0aGUgbGVnZW5kISBZb3UgY2FuIGFsc28gcmVtb3ZlIGEgZ2VudXMgYnkgY2xpY2tpbmcgb24gaXQgb25jZS4gVGhlcmUncyBzb21lIG90aGVyIGZ1bmN0aW9uYWxpdHkgeW91IGNhbiBleHBsb3JlIGluIHRoZSB0b29sYmFyIGF0IHRoZSB0b3Agb2YgdGhlIHBsb3QuIFRoZSBzZWNvbmQgcGxvdCBpcyBhIFBDQSBjb2xvcmVkIGFjY29yZGluZyB0byByZXByb2R1Y3RpdmUgbW9kZS4gSXQgbG9va3MgbGlrZSBhc2V4dWFsIHBvcHVsYXRpb25zIG9jY3VweSBzbGlnaHRseSBsYXJnZXIgbmljaGUgc3BhY2UsIGJ1dCBib3RoIHJlcHJvZHVjdGl2ZSBtb2RlcyBoYXZlIGEgc2ltaWxhciBuaWNoZSBjZW50ZXIuCmBgYHtyIHdhcm5pbmc9RkFMU0V9CiNhZGQgcGNhIHJlc3VsdHMgdG8gbG9jX2NsaW0gZGF0YSBmcmFtZQpsb2NfY2xpbSA8LSBkYXRhLmZyYW1lKGxvY19jbGltLCBjbGltX3BjYSR4KQoKI3VzZSBzb3VyY2VkIHBsb3RfY2xpbV9wY2EgZnVuY3Rpb24gdG8gcGxvdCB0aGUgcGNhIHJlc3VsdHMuIGFyZ3MgYXJlIHRoZSBkYXRhIHNldCB3aXRoIHNwZWNpZXMgbmFtZXMgYW5kIFBDIGF4aXMgdmFsdWVzIGFuZCB0aGUgcGNhIHN1bW1hcnkKYWxsX3BjYSA8LSBwbG90X2NsaW1fcGNhKGxvY19jbGltLCBzdW1tYXJ5X3BjYSwgZmFjdG9yID0gImdlbnVzIikKYWxsX3BjYQoKI3VzZSBzb3VyY2VkIHBsb3RfY2xpbV9wY2EgZnVuY3Rpb24gdG8gcGxvdCB0aGUgcGNhIHJlc3VsdHMuIGFyZ3MgYXJlIHRoZSBkYXRhIHNldCB3aXRoIHNwZWNpZXMgbmFtZXMgYW5kIFBDIGF4aXMgdmFsdWVzIGFuZCB0aGUgcGNhIHN1bW1hcnkKcmVwcm9fcGNhIDwtCiAgcGxvdF9jbGltX3BjYShsb2NfY2xpbSwgc3VtbWFyeV9wY2EsIGZhY3RvciA9ICJyZXByb2R1Y3RpdmVfbW9kZSIpCnJlcHJvX3BjYQoKCiMgc2F2ZSB0aGUgcGxvdCBjb2xvcmVkIGJ5IGdlbnVzCmh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KAogIGFsbF9wY2EsCiAgZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhbGxfc3BlY2llc19wY2FfZ2VudXMuaHRtbCIpLAogIHNlbGZjb250YWluZWQgPSBUUlVFCikKCiMgc2F2ZSB0aGUgcGxvdCBjb2xvcmVkIGJ5IHJlcHJvZHVjdGl2ZSBtb2RlCmh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KAogIHJlcHJvX3BjYSwKICBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFsbF9zcGVjaWVzX3BjYV9yZXByby5odG1sIiksCiAgc2VsZmNvbnRhaW5lZCA9IFRSVUUKKQoKYGBgCgojIyMgU3RhYmlsaXR5CgpFeGFtaW5pbmcgd2hldGhlciBhc2V4dWFsIHBvcHVsYXRpb25zIG9jY3VweSBtb3JlIHVuc3RhYmxlIGNsaW1hdGVzIHRoYW4gc2V4dWFsIHBvcHVsYXRpb25zLiBPbmx5IHVzaW5nIHNwZWNpZXMgd2l0aCBtdWx0aXBsZSBzZXh1YWwgYW5kIGFzZXh1YWwgcG9wdWxhdGlvbnMuIEFzZXh1YWwgcG9wcyB0ZW5kIHRvIG9jY3VweSBtb3JlIHN0YWJsZSB0ZW1wZXJhdHVyZSBlbnZpcm9ubWVudHMsIGJ1dCBsZXNzIHN0YWJsZSBwcmVjaXBpdGF0aW9uIGVudmlyb25tZW50cy4gV2UncmUgZXN0aW1hdGluZyBzdGFiaWxpdHkgdXNpbmcgdGhlIG1ldGhvZCBwcmVzZW50ZWQgYnkgT3dlbnMgYW5kIEd1cmFsbmljayAyMDE5LSBjbGltYXRlU3RhYmlsaXR5OiBBTiBSIFBBQ0tBR0UgVE8gRVNUSU1BVEUgQ0xJTUFURSBTVEFCSUxJVFkgRlJPTSBUSU1FLVNMSUNFIENMSU1BVE9MT0dJRVMuCgpgYGB7ciBjYWNoZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIyMgQ3JlYXRpbmcgdGVtcGVyYXR1cmUgYW5kIHByZWNpcGl0YXRpb24gc3RhYmlsaXR5IGxheWVycwojIyMgVXNpbmcgYmlvMSAoYXZlcmFnZSB0ZW1wKSBhbmQgYmlvMTIgKGF2ZXJhZ2UgcHJlY2lwKQojIyMgMi41IGFyY21pbiByZXNvbHV0aW9uLCBhbHJlYWR5IGNyb3BwZWQgdG8gTlogdG8gc3BlZWQgdXAgY29tcHV0YXRpb24gdGltZQoKCiMgdGltZSBzbGljZXMgYXJlIGNhbGN1bGF0ZWQgYXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgbWlkcG9pbnRzIG9mIHRoZSB0d28gdGltZSBwZXJpb2RzIHRoZSBjbGltYXRlIGxheWVycyB3ZXJlIGNhbGN1bGF0ZWQgZm9yIChlLmcuIG1pZHBvaW50IG9mIExIID0gKDQuMiBrYSAtIDAuMyBrYSkgLyAyICsgMC4zIGthID0gMi4yNSwgbWlkcG9pbnQgb2YgTUggPSAoOC4zMjYga2EgLSA0LjIga2EpIC8gMiArIDQuMiA9IDYuMjYzLiB0aW1lX3NsaWNlID0gNi4yNjMgLSAyLjI1ID0gNC4wMTMpCgojIGMgPSBjdXJyZW50CiMgdF9saCA9IG1pZHBvaW50IHRpbWUgZm9yIGxhdGUgaG9sb2NlbmUKIyB0X21oID0gbWlkLUhvbG9jZW5lCiMgdF9laCA9IGVhcmx5LUhvbG9jZW5lCiMgdF95ZHMgPSBZb3VuZ2VyIERyeWFzIFN0YWRpYWwKIyB0X2JhID0gQsO4bGxpbmctQWxsZXLDuGQKIyB0X2hzID0gSGVpbnJpY2ggU3RhZGlhbCAxCiMgdF9sZ20gPSBMYXN0IEdsYWNpYWwgTWF4aW11bQpjIDwtICgyMDEzIC0gMTk3OSkgLyAyCnRfbGggPC0gKCg0LjIgLSAwLjMpIC8gMiArIDAuMykgKiAxMDAwCnRfbWggPC0gKCg4LjMyNiAtIDQuMikgLyAyICsgNC4yKSAqIDEwMDAKdF9laCA8LSAoKDExLjcgLSA4LjMyNikgLyAyICsgOC4zMjYpICogMTAwMAp0X3lkcyA8LSAoKDEyLjkgLSAxMS43KSAvIDIgKyAxMS43KSAqIDEwMDAKdF9iYSA8LSAoKDE0LjcgLSAxMi45KSAvIDIgKyAxMi45KSAqIDEwMDAKdF9ocyA8LSAoKDE3IC0gMTQuNykgLyAyICsgMTQuNykgKiAxMDAwCnRfbGdtIDwtIDIxMDAwCgp0aW1lX3NsaWNlcyA8LSBjKHRfbGggLSBjLCAKICAgICAgICAgICAgICAgICB0X21oIC0gdF9saCwgCiAgICAgICAgICAgICAgICAgdF9laCAtIHRfbWgsIAogICAgICAgICAgICAgICAgIHRfeWRzIC0gdF9laCwgCiAgICAgICAgICAgICAgICAgdF9iYSAtIHRfeWRzLCAKICAgICAgICAgICAgICAgICB0X2hzIC0gdF9iYSwKICAgICAgICAgICAgICAgICB0X2xnbSAtIHRfaHMpCgoKcHJlY2lwX2RldmlhdGlvbiA8LQogIGNsaW1hdGVTdGFiaWxpdHk6OmRldmlhdGlvblRocm91Z2hUaW1lKHZhcmlhYmxlRGlyZWN0b3J5ID0gcHJlY2lwX3BhdGgsIHRpbWVTbGljZVBlcmlvZCA9IHRpbWVfc2xpY2VzKQoKcHJlY2lwX3N0YWJpbGl0eSA8LSAoMSAvIHByZWNpcF9kZXZpYXRpb24pCnByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIDwtIGNsaW1hdGVTdGFiaWxpdHk6OnJlc2NhbGUwdG8xKHByZWNpcF9zdGFiaWxpdHkpCgojIHdyaXRlIHByZWNpcGl0YXRpb24gc3RhYmlsaXR5IHRvIGZpbGUKd3JpdGVSYXN0ZXIoCiAgcHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsCiAgZmlsZW5hbWUgPSBmaWxlLnBhdGgocmFzdGVyX3BhdGgsICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZC50aWYiKSwKICBmb3JtYXQgPSAiR1RpZmYiLAogIG92ZXJ3cml0ZSA9IFRSVUUKKQoKCnRlbXBfZGV2aWF0aW9uIDwtCiAgY2xpbWF0ZVN0YWJpbGl0eTo6ZGV2aWF0aW9uVGhyb3VnaFRpbWUodmFyaWFibGVEaXJlY3RvcnkgPSB0ZW1wX3BhdGgsIHRpbWVTbGljZVBlcmlvZCA9IHRpbWVfc2xpY2VzKQoKdGVtcF9zdGFiaWxpdHkgPC0gKDEgLyB0ZW1wX2RldmlhdGlvbikKdGVtcF9zdGFiaWxpdHlfc2NhbGVkIDwtIGNsaW1hdGVTdGFiaWxpdHk6OnJlc2NhbGUwdG8xKHRlbXBfc3RhYmlsaXR5KQoKIyB3cml0ZSB0ZW1wZXJhdHVyZSBzdGFiaWxpdHkgdG8gZmlsZQp3cml0ZVJhc3RlcigKICB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsCiAgZmlsZW5hbWUgPSBmaWxlLnBhdGgocmFzdGVyX3BhdGgsICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQudGlmIiksCiAgZm9ybWF0ID0gIkdUaWZmIiwKICBvdmVyd3JpdGUgPSBUUlVFCikKCm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCA8LSBwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCAqIHRlbXBfc3RhYmlsaXR5X3NjYWxlZAoKIyB3cml0ZSBvdmVyYWxsIHN0YWJpbGl0eSB0byBmaWxlCndyaXRlUmFzdGVyKAogIG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwKICBmaWxlbmFtZSA9IGZpbGUucGF0aChyYXN0ZXJfcGF0aCwgIm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZC50aWYiKSwKICBmb3JtYXQgPSAiR1RpZmYiLAogIG92ZXJ3cml0ZSA9IFRSVUUKKQoKdGVtcF9zdGFiaWxpdHlfbWFwIDwtIGdncGxvdCgpICsKICBnZ3NwYXRpYWw6OmxheWVyX3NwYXRpYWwoZGF0YSA9IHRlbXBfc3RhYmlsaXR5X3NjYWxlZCkgKwogIGxhYnModGl0bGUgPSAiVGVtcGVyYXR1cmUgc3RhYmlsaXR5IikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG5hLnZhbHVlID0gInRyYW5zcGFyZW50IikgKwogIHRoZW1lX21pbmltYWwoKQoKcHJlY2lwX3N0YWJpbGl0eV9tYXAgPC0gZ2dwbG90KCkgKwogIGdnc3BhdGlhbDo6bGF5ZXJfc3BhdGlhbChkYXRhID0gcHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQpICsKICBsYWJzKHRpdGxlID0gIlByZWNpcGl0YXRpb24gc3RhYmlsaXR5IikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG5hLnZhbHVlID0gInRyYW5zcGFyZW50IikgKwogIHRoZW1lX21pbmltYWwoKQoKb3ZlcmFsbF9zdGFiaWxpdHlfbWFwIDwtIGdncGxvdCgpICsKICBnZ3NwYXRpYWw6OmxheWVyX3NwYXRpYWwoZGF0YSA9IG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCkgKwogIGxhYnModGl0bGUgPSAiT3ZlcmFsbCBzdGFiaWxpdHkiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MobmEudmFsdWUgPSAidHJhbnNwYXJlbnQiKSArCiAgdGhlbWVfbWluaW1hbCgpCgp0ZW1wX3N0YWJpbGl0eV9tYXAKcHJlY2lwX3N0YWJpbGl0eV9tYXAKb3ZlcmFsbF9zdGFiaWxpdHlfbWFwCgpnZ3NhdmUoInRlbXBfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gdGVtcF9zdGFiaWxpdHlfbWFwLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gbWFwX3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmdnc2F2ZSgicHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IHByZWNpcF9zdGFiaWxpdHlfbWFwLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gbWFwX3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmdnc2F2ZSgib3ZlcmFsbF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBvdmVyYWxsX3N0YWJpbGl0eV9tYXAsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBtYXBfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgoKClBsb3Qgc3RhYmlsaXR5IGFjcm9zcyBzcGVjaWVzLgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCiMgZmlsdGVyIGZvciByZWxldmFudCBzcGVjaWVzIGFuZCBhc2V4dWFsIHJlcHJvZHVjdGl2ZSBtb2RlCmFzZXh1YWxfbG9jcyA8LSBsb2MgJT4lCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSkpICU+JQogIGZpbHRlcigKICAgIHJlcHJvZHVjdGl2ZV9tb2RlID09ICJhc2V4dWFsIiwKICAgIHNwZWNpZXMgPT0gImhvcnJpZHVzIiB8CiAgICAgIHNwZWNpZXMgPT0gImp1Y3VuZHVtIiB8CiAgICAgIHNwZWNpZXMgPT0gImhvb2tlcmkiIHwKICAgICAgc3BlY2llcyA9PSAiYW5udWxhdGEiIHwKICAgICAgc3BlY2llcyA9PSAib3ZvYmVzc3VzIiB8CiAgICAgIHNwZWNpZXMgPT0gImh1dHRvbmkiLAogICAgIWR1cGxpY2F0ZWQobGF0X2xvbmcpCiAgKSAlPiUKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgojIGZpbHRlciBmb3IgcmVsZXZhbnQgc3BlY2llcyBhbmQgc2V4dWFsIHJlcHJvZHVjdGl2ZSBtb2RlCnNleHVhbF9sb2NzIDwtIGxvYyAlPiUKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlKSkgJT4lCiAgZmlsdGVyKAogICAgcmVwcm9kdWN0aXZlX21vZGUgPT0gInNleHVhbCIsCiAgICBzcGVjaWVzID09ICJob3JyaWR1cyIgfAogICAgICBzcGVjaWVzID09ICJqdWN1bmR1bSIgfAogICAgICBzcGVjaWVzID09ICJob29rZXJpIiB8CiAgICAgIHNwZWNpZXMgPT0gImFubnVsYXRhIiB8CiAgICAgIHNwZWNpZXMgPT0gIm92b2Jlc3N1cyIgfAogICAgICBzcGVjaWVzID09ICJodXR0b25pIiwKICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKQogICkgJT4lCiAgZHBseXI6OnNlbGVjdChsb25naXR1ZGUsIGxhdGl0dWRlKQoKIyBleHRyYWN0IHByZWNpcHRpdGF0aW9uIHZhbHVlcyBhbmQgYmluZCBpbnRvIGEgbmV3IGRhdGFmcmFtZQpwcmVjaXBfYXNleHVhbCA8LQogIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgYXNleHVhbF9sb2NzKSAlPiUKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JQogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnByZWNpcF9zZXh1YWwgPC0KICByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIHNleHVhbF9sb2NzKSAlPiUKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JQogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKcHJlY2lwX2RmIDwtIGJpbmRfcm93cyhwcmVjaXBfYXNleHVhbCwgcHJlY2lwX3NleHVhbCkKCiMgcGxvdCBwcmVjaXBpdGF0aW9uIHN0YWJpbGl0eQpwcmVjaXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KAogIGRhdGEgPSBwcmVjaXBfZGYsCiAgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBmaWxsID0gcmVwcm9kdWN0aXZlX21vZGUpCikgKwogIGdlb21fdmlvbGluKHdpZHRoID0gMC44KSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4xLAogICAgICAgICAgICAgICBjb2xvciA9ICJncmF5IiwKICAgICAgICAgICAgICAgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpwcmVjaXBfc3RhYmlsaXR5X3Bsb3QKCiMgZXh0cmFjdCB0ZW1wZXJhdHVyZSB2YWx1ZXMgYW5kIGJpbmQgaW50byBhIG5ldyBkYXRhIGZyYW1lCnRlbXBfYXNleHVhbCA8LQogIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGFzZXh1YWxfbG9jcykgJT4lCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKdGVtcF9zZXh1YWwgPC0KICByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBzZXh1YWxfbG9jcykgJT4lCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmIDwtIGJpbmRfcm93cyh0ZW1wX2FzZXh1YWwsIHRlbXBfc2V4dWFsKQoKIyBwbG90IHRlbXBlcmF0dXJlIHN0YWJpbGl0eQp0ZW1wX3N0YWJpbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gdGVtcF9kZiwKICAgICAgIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGZpbGwgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX3Zpb2xpbih3aWR0aCA9IDAuOCkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuMSwKICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JheSIsCiAgICAgICAgICAgICAgIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKdGVtcF9zdGFiaWxpdHlfcGxvdAoKIyBleHRyYWN0IG92ZXJhbGwgc3RhYmlsaXR5IHZhbHVlcyBhbmQgYmluZCBpbnRvIGEgZGF0YWZyYW1lCm92ZXJhbGxfYXNleHVhbCA8LQogIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGFzZXh1YWxfbG9jcykgJT4lCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKb3ZlcmFsbF9zZXh1YWwgPC0KICByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBzZXh1YWxfbG9jcykgJT4lCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpvdmVyYWxsX2RmIDwtIGJpbmRfcm93cyhvdmVyYWxsX2FzZXh1YWwsIG92ZXJhbGxfc2V4dWFsKQoKIyBwbG90IG92ZXJhbGwgc3RhYmlsaXR5Cm92ZXJhbGxfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KAogIGRhdGEgPSBvdmVyYWxsX2RmLAogIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGZpbGwgPSByZXByb2R1Y3RpdmVfbW9kZSkKKSArCiAgZ2VvbV92aW9saW4od2lkdGggPSAwLjgpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjEsCiAgICAgICAgICAgICAgIGNvbG9yID0gImdyYXkiLAogICAgICAgICAgICAgICBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCm92ZXJhbGxfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgidGVtcF9zdGFiaWxpdHlfcGxvdC5wbmciLAogICAgICAgcGxvdCA9IHRlbXBfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmdnc2F2ZSgicHJlY2lwX3N0YWJpbGl0eV9wbG90LnBuZyIsCiAgICAgICBwbG90ID0gcHJlY2lwX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpnZ3NhdmUoIm92ZXJhbGxfc3RhYmlsaXR5X3Bsb3QucG5nIiwKICAgICAgIHBsb3QgPSBvdmVyYWxsX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCmBgYAoKCgojIyBFbnZpcm9ubWVudGFsIHNwYWNlIHBlciBzcGVjaWVzIHsudGFic2V0fQpUaGVzZSBhcmUgUENBcyBvZiBlbnZpcm9ubWVudGFsIHNwYWNlIGZvciBzcGVjaWVzIHdpdGhpbiBnZW5lcmEuIEVhY2ggY2xpbWF0ZSBQQ0EgaXMgb2YgbG9jYWxpdGllcyBmb3IgYSBzaW5nbGUgZ2VudXMsIGNvbG9yZWQgYnkgc3BlY2llcy4gSSdtIGRvaW5nIHRoaXMgZXZlbiBmb3IgZ2VuZXJhIHdpdGggb25lIHNwZWNpZXMsIHNvIGl0J3MgZWFzeSB0byBzZWUgaWYgY2VydGFpbiBsb2NhbGl0aWVzIGdyb3VwIHRvZ2V0aGVyLiAKCkknbSBhbHNvIGNvbmR1Y3RpbmcgRW52aXJvbWVudGFsIE5pY2hlIEZhY3RvciBBbmFseXNpcyB0byBpbnZlc3RpZ2F0ZSB0aGUgaW5mbHVlbmNlIG9mIHJlcHJvZHVjdGl2ZSBtb2RlIG9uIG5pY2hlIG1hcmdpbmFsaXR5LgoKIyMjIEFyZ29zYXJjaHVzIGhvcnJpZHVzCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgY29uZHVjdCBwY2EKc3VtbWFyeV9saXN0X2Fob3IgPC0gc3BlY2llc19wY2FfZnVuKGRhdGEgPSBsb2NfY2xpbSwgZ2VudXMgPSAiYXJnb3NhcmNodXMiLCBzcGVjaWVzID0gImhvcnJpZHVzIikKCiMgcGxvdAphaG9yX3Bsb3QgPC0KICBwbG90X2NsaW1fcGNhKHN1bW1hcnlfbGlzdF9haG9yJGxvY19jbGltLAogICAgICAgICAgICAgICAgc3VtbWFyeV9saXN0X2Fob3Ikc3VtbWFyeV9wY2EsCiAgICAgICAgICAgICAgICBmYWN0b3IgPSAicmVwcm9kdWN0aXZlX21vZGUiKQphaG9yX3Bsb3QKCmh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KGFob3JfcGxvdCwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhaG9yX3BjYS5odG1sIiksCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGZjb250YWluZWQgPSBUUlVFKQoKI2ZpbHRlciBsb2NhbGl0aWVzIGZvciB0aGUgZm9jYWwgc3BlY2llcwphaG9yX2xvYyA8LSBsb2MgJT4lCiAgZmlsdGVyKGdlbnVzID09ICJhcmdvc2FyY2h1cyIsIHNwZWNpZXMgPT0gImhvcnJpZHVzIikKCiN1c2Ugc291cmNlZCBwbG90X2xvY3NfbGVhZmxldCBzY3JpcHQgdG8gcGxvdCBsb2NhbGl0aWVzCmFob3JfbWFwIDwtIHBsb3RfbG9jc19sZWFmbGV0KGFob3JfbG9jLCAicmVwcm9kdWN0aXZlX21vZGUiKQoKYWhvcl9tYXAKCm1hcHZpZXc6Om1hcHNob3QoCiAgYWhvcl9tYXAsCiAgdXJsID0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhaG9yX21hcC5odG1sIiksCiAgZmlsZSA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiYWhvcl9tYXAucGRmIikKKQoKCmBgYAoKYGBge3J9CnN1bW1hcnlfbGlzdF9haG9yJHN1bW1hcnlfcGNhCmxvYWRpbmdzX2Fob3IgPC0gc3VtbWFyeV9saXN0X2Fob3Ikc3VtbWFyeV9wY2Ekcm90YXRpb24Ka25pdHI6OmthYmxlKHJvdW5kKGxvYWRpbmdzX2Fob3JbLCAxOjNdLCAzKSkgI1RhYmxlIG9mIGxvYWRpbmcgc2NvcmVzIGZvciB0aGUgZmlyc3QgMyBQQ3MuIApgYGAKCiMjIyMgRU5GQQpOb3cgSSdtIGdvaW5nIHRvIHRvIGVudmlyb25tZW50YWwgbmljaGUgZmFjdG9yIGFuYWx5c2lzIGJldHdlZW4gc2V4dWFsIGFuZCBhc2V4dWFsIHBvcHVsYXRpb25zIHdpdGhpbiB0aGUgc3BlY2llcy4KYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI2dldCBiYWNrZ3JvdW5kIGVudid0IGZvciB0aGUgc3BlY2llcwphaG9yX2JnX2VudiA8LSBiZ19lbnZfY3JvcChhaG9yX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiaG9ycmlkdXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCA9IHcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIgPSAwLjUpCgojZW5mYSBmb3IgdGhlIHNleHVhbCBzcGVjaWVzCmFob3Jfc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gYWhvcl9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJob3JyaWR1cyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IGFob3JfYmdfZW52KQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKYWhvcl9hc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gYWhvcl9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiaG9ycmlkdXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBhaG9yX2JnX2VudikKCgojcGxvdCB0aGUgbWFyZ2luYWxpdHkgc2NvcmVzCmFob3JfbWFyZ2luYWxpdHkgPC0gbWFyZ2luYWxpdHlfbG9sbGlwb3Aoc2V4X21hcmcgPSBhaG9yX3NleHVhbF9lbmZhJG0sIAogICAgICAgICAgICAgICAgICAgIGFzZXhfbWFyZyA9IGFob3JfYXNleHVhbF9lbmZhJG0sCiAgICAgICAgICAgICAgICAgICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQXJnb3NhcmNodXMgaG9ycmlkdXMiKQoKIyB3cml0ZSBzY29yZXMgdG8gY3N2cwpyZWFkcjo6d3JpdGVfY3N2KAogIGFob3JfYXNleHVhbF9lbmZhJG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgYWhvcl9zZXh1YWxfZW5mYSRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFob3Jfc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCmdnc2F2ZSgiYWhvcl9tYXJnaW5hbGl0eV9sb2xsaXBvcC5wbmciLAogICAgICAgcGxvdCA9IGFob3JfbWFyZ2luYWxpdHksCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCgpgYGAKCkEgY291cGxlIGRpZmZlcmVudCB3YXlzIHRvIHZpc3VhbGl6ZSB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24uIDEpIFNjYXR0ZXJwbG90IHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IHZzIGF4aXMgMSBvZiB0aGUgc3BlY2lhbGl6YXRpb24gd2l0aCB0aGUgbGFiZWxzIHJlbW92ZWQgKHRoZXkgbWFrZSB0aGluZ3MgaW5kaXNjZXJuYWJsZSkuIFJlZCA9IG9jY3VwaWVkIGUtc3BhY2UuIEdyYXkgPSBCYWNrZ3JvdW5kIGUtc3BhY2UuIFRoZSB5ZWxsb3cgZG90IGluZGljYXRlcyB0aGUgbWVhbiBtYXJnaW5hbGl0eSAoaXQncyBub3QgdGhlIHZhbHVlIHRoYXQgaXMgb24gdGhlIGxvbGxpcG9wIHBsb3QsIHNvIGRvbid0IGxldCB0aGF0IGNvbmZ1c2UgeW91KS4gMikgRU5GQSBoaXN0b2dyYW0gdmlzdWFsaXphdGlvbnMgb2YgbWFyZ2luYWxpdHkgYW5kIHNwZWNpYWxpemF0aW9uIGF4ZXMuIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlIHdpdGggY29sb3JzIGNvcnJlc3BvbmRpbmcgdG8gc2V4dWFsIHZzLiBhc2V4dWFsIHBvcHVsYXRpb25zLiAKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKYWhvcl9hc2V4dWFsX2RmIDwtIGFob3JfYXNleHVhbF9lbmZhJGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gYWhvcl9hc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KGFob3JfYXNleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9hc2V4dWFsX21hcmdpbmFsaXR5X2RmLmNzdiIpKQoKYWhvcl9zZXh1YWxfZGYgPC0gYWhvcl9zZXh1YWxfZW5mYSRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IGFob3Jfc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KGFob3Jfc2V4dWFsX2RmLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhaG9yX3NleHVhbF9tYXJnaW5hbGl0eV9kZi5jc3YiKSkKCiNhc2V4dWFsCmFob3JfZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChhaG9yX2FzZXh1YWxfZGYsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIkFzZXh1YWwiKQoKYWhvcl9lbmZhX3NwZWNfYXNleHVhbAoKZ2dzYXZlKCJhaG9yX2VuZmFfc3BlY19hc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gYWhvcl9lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKI3NleHVhbAphaG9yX2VuZmFfc3BlY19zZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChhaG9yX3NleHVhbF9kZiwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiU2V4dWFsIikKCmFob3JfZW5mYV9zcGVjX3NleHVhbAoKZ2dzYXZlKCJhaG9yX2VuZmFfc3BlY19zZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBhaG9yX2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojIyBhc2V4dWFsCmhpc3QoYWhvcl9hc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCiMgd3JpdGUgdG8gZmlsZQpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiYWhvcl9hc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChhaG9yX2FzZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiMjIHNleHVhbApoaXN0KGFob3Jfc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKIyB3cml0ZSB0byBmaWxlCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJhaG9yX3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QoYWhvcl9zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCmFob3JfdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gYWhvcl9iZ19lbnYsIGxvY3MgPSBhaG9yX2xvYywgZ2VudXMgPSAiQXJnb3NhcmNodXMiLCBzcGVjaWVzID0gImhvcnJpZHVzIikKCmFob3JfdG90YWxfcGNhCgpnZ3NhdmUoImFob3JfdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gYWhvcl90b3RhbF9wY2EsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKYGBgCgojIyMjIyBFTkZBIFJlZHVjZWQKVHJ5aW5nIG91dCBhIHJlcGVhdCBvZiB0aGUgYW5hbHlzZXMgd2l0aCByZWR1Y2VkIGVudmlyb25tZW50YWwgc3BhY2UuClByaW9yaXRpemluZyB2YXJpYWJsZXMgdGhhdCB3aWxsIGxpbWl0IHRoZWlyIGRpc3RyaWJ1dGlvbiAoaS5lLiB2YXJpYWJsZXMgdGhhdCByZXByZXNlbnQgdGhlIGV4dHJlbWVzKS4gQWZ0ZXIgY29ycmVsYXRpb24gYW5hbHlzaXMsIHdlJ3JlIGxlZnQgd2l0aCBCSU82LCBCSU8xMywgQklPMTQsIEJJTzE2CmBgYHtyIGNhY2hlPVRSVUV9CiMgUENBIG9mIGJhY2tncm91bmQgZS1zcGFjZS4gUmVzdWx0aW5nIGxpc3QgaXMgYSBjb3JyZWxhdGlvbiBoZWF0bWFwIChjb3JfaGVhdG1hcCksIGEgdGliYmxlIG9mIHRoZSByYXN0ZXJzIHdpdGggY29ycmVsYXRpb24gPiB0aGUgY3V0b2ZmIChkZWZhdWx0IGlzIDAuNzUpLCBhbmQgYSB0aWJibGUgb2YgYWxsIHBhaXJ3aXNlIGNvcnJlbGF0aW9ucwphaG9yX3BjYSA8LSByYXN0ZXJfY29ycmVsYXRpb24ocmFzdGVyX3N0YWNrID0gYWhvcl9iZ19lbnYpCmFob3JfcGNhJGNvcl9oZWF0bWFwCmFob3JfcGNhJHRvcF9jb3IgJT4lIGtuaXRyOjprYWJsZSgpCgpnZ3NhdmUoImFob3JfcGNhX2NvcnIucG5nIiwKICAgICAgIHBsb3QgPSBhaG9yX3BjYSRjb3JfaGVhdG1hcCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKCiMgd3JpdGUgY29ycmVsYXRpb24gZGF0YSBmcmFtZSB0byBmaWxlCnJlYWRyOjp3cml0ZV9jc3YoYWhvcl9wY2EkdG9wX2NvciwgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl90b3BfY29yLmNzdiIpKQpgYGAKClJlcGVhdCB0aGUgYW5hbHlzaXMgd2l0aCB0aGUgcmVkdWNlZCBkYXRhIHNldC4gVGhlIGJhY2tncm91bmQgZW52aXJvbm1lbnQgaXMgMC41IGRlZ3JlZXMsIGEgYmFsbHBhcmsgZGlzcGVyc2FsIGxpbWl0YXRpb24gZm9yIGFsbCBzdGljayBpbnNlY3Qgc3BlY2llcyBpbiB0aGlzIHN0dWR5LgpgYGB7cn0Kd19haG9yIDwtIHJhc3Rlcjo6c3Vic2V0KHcsIGMoImJpbzYiLCAiYmlvMTMiLCAiYmlvMTQiLCAiYmlvMTYiKSkKCiNnZXQgYmFja2dyb3VuZCBlbnYndCBmb3IgdGhlIHNwZWNpZXMKYWhvcl9iZ19lbnZfc3Vic2V0IDwtIGJnX2Vudl9jcm9wKGFob3JfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJob3JyaWR1cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50ID0gd19haG9yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gMC41KQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwphaG9yX3NleHVhbF9lbmZhX3N1YnNldCA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBhaG9yX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImhvcnJpZHVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hc2tfcmFzdGVyID0gYWhvcl9iZ19lbnZfc3Vic2V0KQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKYWhvcl9hc2V4dWFsX2VuZmFfc3Vic2V0IDwtIGVuZmFfY2FsY19mdW4obG9jcyA9IGFob3JfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImhvcnJpZHVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hc2tfcmFzdGVyID0gYWhvcl9iZ19lbnZfc3Vic2V0KQoKIyB3cml0ZSBtYXJnaW5hbGl0eSBzY29yZXMgdG8gY3N2CnJlYWRyOjp3cml0ZV9jc3YoCiAgYWhvcl9hc2V4dWFsX2VuZmFfc3Vic2V0JG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9zdWJzZXRfYXNleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgpyZWFkcjo6d3JpdGVfY3N2KAogIGFob3Jfc2V4dWFsX2VuZmFfc3Vic2V0JG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9zdWJzZXRfc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCiNwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKYWhvcl9zdWJzZXRfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gYWhvcl9zZXh1YWxfZW5mYV9zdWJzZXQkbSwKICAgIGFzZXhfbWFyZyA9IGFob3JfYXNleHVhbF9lbmZhX3N1YnNldCRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQXJnb3NhcmNodXMgaG9ycmlkdXMiCiAgKQoKYWhvcl9zdWJzZXRfbWFyZ2luYWxpdHkKCmdnc2F2ZSgiYWhvcl9zdWJzZXRfbWFyZ2luYWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBhaG9yX3N1YnNldF9tYXJnaW5hbGl0eSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgpWaXN1YWxpemUgd2l0aCByZWR1Y2VkIGRhdGEgc2V0CmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKYWhvcl9hc2V4dWFsX2RmX3N1YnNldCA8LSBhaG9yX2FzZXh1YWxfZW5mYV9zdWJzZXQkbGkgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgYmluZF9jb2xzKHByID0gYWhvcl9hc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICBhaG9yX2FzZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFob3Jfc3Vic2V0X2FzZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikKKQoKYWhvcl9zZXh1YWxfZGZfc3Vic2V0IDwtIGFob3Jfc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JQogIGFzX3RpYmJsZSgpICU+JQogIGJpbmRfY29scyhwciA9IGFob3Jfc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICBhaG9yX3NleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9zdWJzZXRfc2V4dWFsX21hcmdpbmFsaXR5X2RmLmNzdiIpCikKCiNhc2V4dWFsLiBKZXN1cyB0aGVzZSB2YXJpYWJsZSBuYW1lcyBhcmUgZ2V0dGluZyBsb25nCmFob3Jfc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsIDwtCiAgZW5mYV9oZXhfcGxvdCgKICAgIGFob3JfYXNleHVhbF9kZl9zdWJzZXQsCiAgICBtYXJnID0gTWFyLAogICAgc3BlYyA9IFNwZTEsCiAgICByZXByb19tb2RlID0gIkFzZXh1YWwiCiAgKQoKYWhvcl9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwKCmdnc2F2ZSgKICAiYWhvcl9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICBwbG90ID0gYWhvcl9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwsCiAgZGV2aWNlID0gInBuZyIsCiAgcGF0aCA9IHBsb3RfcGF0aCwKICBkcGkgPSAicmV0aW5hIgopCgojIHNleHVhbAphaG9yX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsIDwtCiAgZW5mYV9oZXhfcGxvdCgKICAgIGFob3Jfc2V4dWFsX2RmX3N1YnNldCwKICAgIG1hcmcgPSBNYXIsCiAgICBzcGVjID0gU3BlMSwKICAgIHJlcHJvX21vZGUgPSAiU2V4dWFsIgogICkKCmFob3Jfc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwKCmdnc2F2ZSgKICAiYWhvcl9zdWJzZXRfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogIHBsb3QgPSBhaG9yX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsLAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiMgYXNleHVhbApoaXN0KGFob3JfYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImFob3Jfc3Vic2V0X2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGFob3JfYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiMgc2V4dWFsCmhpc3QoYWhvcl9zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImFob3Jfc3Vic2V0X3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QoYWhvcl9zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiMjIyAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZQphaG9yX3N1YnNldF90b3RhbF9wY2EgPC0KICB0b3RhbF9jbGltYXRlX3BjYV9wbG90KAogICAgYmdfZW52ID0gYWhvcl9iZ19lbnZfc3Vic2V0LAogICAgbG9jcyA9IGFob3JfbG9jLAogICAgZ2VudXMgPSAiQXJnb3NhcmNodXMiLAogICAgc3BlY2llcyA9ICJob3JyaWR1cyIKICApCgphaG9yX3N1YnNldF90b3RhbF9wY2EKCmdnc2F2ZSgKICAiYWhvcl9zdWJzZXRfdG90YWxfcGNhLnBuZyIsCiAgcGxvdCA9IGFob3Jfc3Vic2V0X3RvdGFsX3BjYSwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKCiMgc2F2ZSBlbmZhIG9iamVjdHMgYW5kIHJlbW92ZSB0aGVtIGZyb20gdGhlIGVudmlyb25tZW50LiBUaGV5IHRha2UgdXAgYSBsb3Qgb2YgbWVtb3J5LgpzYXZlUkRTKGFob3Jfc2V4dWFsX2VuZmEsIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJhaG9yX3NleHVhbF9lbmZhLlJEUyIpKQpybShhaG9yX3NleHVhbF9lbmZhKQoKc2F2ZVJEUyhhaG9yX2FzZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgImFob3JfYXNleHVhbF9lbmZhLlJEUyIpKQpybShhaG9yX2FzZXh1YWxfZW5mYSkKCnNhdmVSRFMoYWhvcl9zZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgImFob3Jfc3Vic2V0X3NleHVhbF9lbmZhLlJEUyIpKQpybShhaG9yX3NleHVhbF9lbmZhX3N1YnNldCkKCnNhdmVSRFMoYWhvcl9hc2V4dWFsX2VuZmFfc3Vic2V0LAogICAgICAgIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJhaG9yX3N1YnNldF9hc2V4dWFsX2VuZmEuUkRTIikpCnJtKGFob3JfYXNleHVhbF9lbmZhX3N1YnNldCkKYGBgCgojIyMjIFN0YWJpbGl0eQpXZSdyZSBhbHNvIGludGVyZXN0ZWQgaW4gc2VlaW5nIGlmIGFzZXh1YWwgcG9wdWxhdGlvbnMgbGl2ZSBpbiBtb3JlIHVuc3RhYmxlIGNsaW1hdGljIGFyZWFzIHJlbGF0aXZlIHRvIHNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyfQphaG9yX2xvY3NfYXNleHVhbCA8LSBhaG9yX2xvYyAlPiUgCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSwgc2VwID0gIl8iKSkgJT4lIAogIGZpbHRlcihyZXByb2R1Y3RpdmVfbW9kZSA9PSAiYXNleHVhbCIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCmFob3JfbG9jc19zZXh1YWwgPC0gYWhvcl9sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gInNleHVhbCIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCnByZWNpcF9hc2V4dWFsX2Fob3IgPC0gcmFzdGVyOjpleHRyYWN0KHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBhaG9yX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnByZWNpcF9zZXh1YWxfYWhvciA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGFob3JfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnByZWNpcF9kZl9haG9yIDwtIGJpbmRfcm93cyhwcmVjaXBfYXNleHVhbF9haG9yLCBwcmVjaXBfc2V4dWFsX2Fob3IpCgpyZWFkcjo6d3JpdGVfY3N2KHByZWNpcF9kZl9haG9yLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhaG9yX3ByZWNpcF9zdGFiaWxpdHlfZGYuY3N2IikpCgphaG9yX3ByZWNpcF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHByZWNpcF9kZl9haG9yLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gcHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmFob3JfcHJlY2lwX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoCiAgImFob3JfcHJlY2lwX3N0YWJpbGl0eS5wbmciLAogIHBsb3QgPSBhaG9yX3ByZWNpcF9zdGFiaWxpdHlfcGxvdCwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKCnRlbXBfYXNleHVhbF9haG9yIDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGFob3JfbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnRlbXBfc2V4dWFsX2Fob3IgPC0gcmFzdGVyOjpleHRyYWN0KHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgYWhvcl9sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnRlbXBfZGZfYWhvciA8LSBiaW5kX3Jvd3ModGVtcF9hc2V4dWFsX2Fob3IsIHRlbXBfc2V4dWFsX2Fob3IpCgpyZWFkcjo6d3JpdGVfY3N2KHRlbXBfZGZfYWhvciwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl90ZW1wX3N0YWJpbGl0eV9kZi5jc3YiKSkKCmFob3JfdGVtcF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHRlbXBfZGZfYWhvciwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKYWhvcl90ZW1wX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoCiAgImFob3JfdGVtcF9zdGFiaWxpdHkucG5nIiwKICBwbG90ID0gYWhvcl90ZW1wX3N0YWJpbGl0eV9wbG90LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQoKb3ZlcmFsbF9hc2V4dWFsX2Fob3IgPC0gcmFzdGVyOjpleHRyYWN0KG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgYWhvcl9sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKb3ZlcmFsbF9zZXh1YWxfYWhvciA8LSByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBhaG9yX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKb3ZlcmFsbF9kZl9haG9yIDwtIGJpbmRfcm93cyhvdmVyYWxsX2FzZXh1YWxfYWhvciwgb3ZlcmFsbF9zZXh1YWxfYWhvcikKCnJlYWRyOjp3cml0ZV9jc3Yob3ZlcmFsbF9kZl9haG9yLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhaG9yX292ZXJhbGxfc3RhYmlsaXR5X2RmLmNzdiIpKQoKCmFob3Jfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IG92ZXJhbGxfZGZfYWhvciwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKYWhvcl9vdmVyYWxsX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoCiAgImFob3Jfb3ZlcmFsbF9zdGFiaWxpdHkucG5nIiwKICBwbG90ID0gYWhvcl9vdmVyYWxsX3N0YWJpbGl0eV9wbG90LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQoKYGBgCgojIyMjIFNlYXNvbmFsaXR5CmBgYHtyfQpzZWFzX3ByZWNpcF9hc2V4dWFsX2Fob3IgPC0gcmFzdGVyOjpleHRyYWN0KHckYmlvMTUsIGFob3JfbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnNlYXNfcHJlY2lwX3NleHVhbF9haG9yIDwtIHJhc3Rlcjo6ZXh0cmFjdCh3JGJpbzE1LCBhaG9yX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKc2Vhc19wcmVjaXBfZGZfYWhvciA8LSBiaW5kX3Jvd3Moc2Vhc19wcmVjaXBfYXNleHVhbF9haG9yLCBzZWFzX3ByZWNpcF9zZXh1YWxfYWhvcikKCnJlYWRyOjp3cml0ZV9jc3Yoc2Vhc19wcmVjaXBfZGZfYWhvciwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9wcmVjaXBfc2Vhc29uYWxpdHlfZGYuY3N2IikpCgphaG9yX3ByZWNpcF9zZWFzb25hbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gc2Vhc19wcmVjaXBfZGZfYWhvciwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zZWFzb25hbGl0eSwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKYWhvcl9wcmVjaXBfc2Vhc29uYWxpdHlfcGxvdAoKZ2dzYXZlKAogICJhaG9yX3ByZWNpcF9zZWFzb25hbGl0eS5wbmciLAogIHBsb3QgPSBhaG9yX3ByZWNpcF9zZWFzb25hbGl0eV9wbG90LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQoKc2Vhc190ZW1wX2FzZXh1YWxfYWhvciA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW80LCBhaG9yX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc2Vhc29uYWxpdHkiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKc2Vhc190ZW1wX3NleHVhbF9haG9yIDwtIHJhc3Rlcjo6ZXh0cmFjdCh3JGJpbzQsIGFob3JfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKc2Vhc190ZW1wX2RmX2Fob3IgPC0gYmluZF9yb3dzKHNlYXNfdGVtcF9hc2V4dWFsX2Fob3IsIHNlYXNfdGVtcF9zZXh1YWxfYWhvcikKCnJlYWRyOjp3cml0ZV9jc3Yoc2Vhc190ZW1wX2RmX2Fob3IsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFob3JfdGVtcF9zZWFzb25hbGl0eV9kZi5jc3YiKSkKCmFob3JfdGVtcF9zZWFzb25hbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gc2Vhc190ZW1wX2RmX2Fob3IsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3NlYXNvbmFsaXR5LCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgphaG9yX3RlbXBfc2Vhc29uYWxpdHlfcGxvdAoKZ2dzYXZlKAogICJhaG9yX3RlbXBfc2Vhc29uYWxpdHkucG5nIiwKICBwbG90ID0gYWhvcl90ZW1wX3NlYXNvbmFsaXR5X3Bsb3QsCiAgZGV2aWNlID0gInBuZyIsCiAgcGF0aCA9IHBsb3RfcGF0aCwKICBkcGkgPSAicmV0aW5hIgopCgpgYGAKCgoKCgojIyMjIE1vdmUgb3V0cHV0ClB1dCBhbGwgb3V0cHV0IGludG8gc3BlY2llcy1zcGVjaWZpYyBzdWJmb2xkZXJzLgpgYGB7ciByZXN1bHRzPSJoaWRlIn0KYWhvcl9vdXRfaW50X3BhdGggPC0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhcmdvc2FyY2h1c19ob3JyaWR1cyIpCmFob3Jfb3V0X3Bsb3RfcGF0aCA8LSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiYXJnb3NhcmNodXNfaG9ycmlkdXMiKQphaG9yX291dF9zcHJlYWRfcGF0aCA8LSBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhcmdvc2FyY2h1c19ob3JyaWR1cyIpCmFob3Jfb3V0X29ial9wYXRoIDwtIGZpbGUucGF0aChvYmpfcGF0aCwgImFyZ29zYXJjaHVzX2hvcnJpZHVzIikKCiMgbW92ZSBpbnRlcmFjdGl2ZQptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IGludGVyYWN0aXZlX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IGFob3Jfb3V0X2ludF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJhaG9yIikKIyBtb3ZlIHBsb3RzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gcGxvdF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhaG9yX291dF9wbG90X3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gImFob3IiKQoKIyBtb3ZlIHNwcmVhZHNoZWV0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHNwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhaG9yX291dF9zcHJlYWRfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiYWhvciIpCgojIG1vdmUgb2JqZWN0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IG9ial9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhaG9yX291dF9vYmpfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiYWhvciIpCmBgYAoKCgojIyMgQXN0ZWxpYXBoYXNtYSBqdWN1bmR1bQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojcGNhCnN1bW1hcnlfbGlzdF9hanVjIDwtIHNwZWNpZXNfcGNhX2Z1bihsb2NfY2xpbSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW51cyA9ImFzdGVsaWFwaGFzbWEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAianVjdW5kdW0iKQojcGxvdAphanVjX3Bsb3QgPC0gcGxvdF9jbGltX3BjYShzdW1tYXJ5X2xpc3RfYWp1YyRsb2NfY2xpbSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcnlfbGlzdF9hanVjJHN1bW1hcnlfcGNhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yID0gInJlcHJvZHVjdGl2ZV9tb2RlIikKYWp1Y19wbG90CgojaWYgc2VsZmNvbnRhaW5lZCA9IFRSVUUsIHlvdSBjYW4gcmVtb3ZlIHRoZSBmb2xkZXIgdGhhdCBnZXRzIGFkZGVkIGFsb25nc2lkZSB0aGUgcGxvdC4gCmh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KGFqdWNfcGxvdCwgZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhanVjX3BjYS5odG1sIiksIHNlbGZjb250YWluZWQgPSBUUlVFKQoKI2ZpbHRlciBsb2NhbGl0aWVzIGZvciB0aGUgZm9jYWwgc3BlY2llcwphanVjX2xvYyA8LSBsb2MgJT4lIAogIGZpbHRlcihnZW51cyA9PSAiYXN0ZWxpYXBoYXNtYSIsIHNwZWNpZXMgPT0gImp1Y3VuZHVtIikKICAKI3VzZSBzb3VyY2VkIHBsb3RfbG9jc19sZWFmbGV0IHNjcmlwdCB0byBwbG90IGxvY2FsaXRpZXMKYWp1Y19tYXAgPC0gcGxvdF9sb2NzX2xlYWZsZXQoYWp1Y19sb2MsICJyZXByb2R1Y3RpdmVfbW9kZSIpCgphanVjX21hcAoKIyBzYXZlIHRoZSBtYXAKbWFwdmlldzo6bWFwc2hvdChhanVjX21hcCwgdXJsID0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhanVjX21hcC5odG1sIiksIGZpbGUgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFqdWNfbWFwLnBkZiIpKQoKYGBgCgoKCmBgYHtyfQpzdW1tYXJ5X2xpc3RfYXN0ZSRzdW1tYXJ5X3BjYQpsb2FkaW5nc19hc3RlIDwtIHN1bW1hcnlfbGlzdF9hc3RlJHN1bW1hcnlfcGNhJHJvdGF0aW9uCmtuaXRyOjprYWJsZShyb3VuZChsb2FkaW5nc19hc3RlWywxOjNdLDMpKSAjVGFibGUgb2YgbG9hZGluZyBzY29yZXMgZm9yIHRoZSBmaXJzdCAzIFBDcy4gCmBgYAoKIyMjIyBFTkZBCgpOb3cgSSdtIGdvaW5nIHRvIHRvIGVudmlyb25tZW50YWwgbmljaGUgZmFjdG9yIGFuYWx5c2lzIGJldHdlZW4gc2V4dWFsIGFuZCBhc2V4dWFsIHBvcHVsYXRpb25zIHdpdGhpbiB0aGUgc3BlY2llcy4KYGBge3Igd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlPUZBTFNFfQojZ2V0IGJhY2tncm91bmQgZW52J3QgZm9yIHRoZSBzcGVjaWVzCmFqdWNfYmdfZW52IDwtIGJnX2Vudl9jcm9wKGFzdGVfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJqdWN1bmR1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50ID0gdywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciA9IDAuNSkKCiNlbmZhIGZvciB0aGUgc2V4dWFsIHNwZWNpZXMKYWp1Y19zZXh1YWxfZW5mYSA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBhc3RlX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImp1Y3VuZHVtIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hc2tfcmFzdGVyID0gYWp1Y19iZ19lbnYpCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwphanVjX2FzZXh1YWxfZW5mYSA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBhc3RlX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJqdWN1bmR1bSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IGFqdWNfYmdfZW52KQoKCiNwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKYWp1Y19tYXJnaW5hbGl0eSA8LSAgbWFyZ2luYWxpdHlfbG9sbGlwb3Aoc2V4X21hcmcgPSBhanVjX3NleHVhbF9lbmZhJG0sIAogICAgICAgICAgICAgICAgICAgIGFzZXhfbWFyZyA9IGFqdWNfYXNleHVhbF9lbmZhJG0sCiAgICAgICAgICAgICAgICAgICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQXN0ZWxpYXBoYXNtYSBqdWN1bmR1bSIpCgphanVjX21hcmdpbmFsaXR5CgojIHdyaXRlIHNjb3JlcyB0byBjc3ZzCnJlYWRyOjp3cml0ZV9jc3YoCiAgYWp1Y19hc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhanVjX2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICBhanVjX3NleHVhbF9lbmZhJG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKZ2dzYXZlKCJhanVjX21hcmdpbmFsaXR5X2xvbGxpcG9wLnBuZyIsCiAgICAgICBwbG90ID0gYWp1Y19tYXJnaW5hbGl0eSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQpgYGAKCkEgY291cGxlIGRpZmZlcmVudCB3YXlzIHRvIHZpc3VhbGl6ZSB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24uIDEpIFNjYXR0ZXJwbG90IHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IHZzIGF4aXMgMSBvZiB0aGUgc3BlY2lhbGl6YXRpb24gd2l0aCB0aGUgbGFiZWxzIHJlbW92ZWQgKHRoZXkgbWFrZSB0aGluZ3MgaW5kaXNjZXJuYWJsZSkuIFJlZCA9IG9jY3VwaWVkIGUtc3BhY2UuIEdyYXkgPSBCYWNrZ3JvdW5kIGUtc3BhY2UuIDIpIEVORkEgaGlzdG9ncmFtIHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IGFuZCBzcGVjaWFsaXphdGlvbiBheGVzLiAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZSB3aXRoIGNvbG9ycyBjb3JyZXNwb25kaW5nIHRvIHNleHVhbCB2cy4gYXNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKYWp1Y19hc2V4dWFsX2RmIDwtIGFqdWNfYXNleHVhbF9lbmZhJGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gYWp1Y19hc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KGFqdWNfYXNleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19hc2V4dWFsX21hcmdpbmFsaXR5X2RmLmNzdiIpKQoKCmFqdWNfc2V4dWFsX2RmIDwtIGFqdWNfc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBhanVjX3NleHVhbF9lbmZhJHByKQoKcmVhZHI6OndyaXRlX2NzdihhanVjX3NleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19zZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgojYXNleHVhbAphanVjX2VuZmFfc3BlY19hc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QoYWp1Y19hc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgiYWp1Y19lbmZhX3NwZWNfYXNleHVhbC5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfZW5mYV9zcGVjX2FzZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiNzZXh1YWwKYWp1Y19lbmZhX3NwZWNfc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QoYWp1Y19zZXh1YWxfZGYsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoImFqdWNfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfZW5mYV9zcGVjX3NleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiNhc2V4dWFsCmhpc3QoYWp1Y19hc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJhanVjX2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGFqdWNfYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyBzZXh1YWwKaGlzdChhanVjX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJhanVjX3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QoYWp1Y19zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCmFqdWNfdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gYWp1Y19iZ19lbnYsIGxvY3MgPSBhc3RlX2xvYywgZ2VudXMgPSAiQXN0ZWxpb3BoYXNtYSIsIHNwZWNpZXMgPSAianVjdW5kdW0iKQoKYWp1Y190b3RhbF9wY2EKCmdnc2F2ZSgiYWp1Y190b3RhbF9wY2EucG5nIiwKICAgICAgIHBsb3QgPSBhanVjX3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQpgYGAKCiMjIyMjIEVORkEgUmVkdWNlZAoKVHJ5aW5nIG91dCBhIHJlcGVhdCBvZiB0aGUgYW5hbHlzZXMgd2l0aCByZWR1Y2VkIGVudmlyb25tZW50YWwgc3BhY2UuClByaW9yaXRpemluZyB2YXJpYWJsZXMgdGhhdCB3aWxsIGxpbWl0IHRoZWlyIGRpc3RyaWJ1dGlvbiAoaS5lLiB2YXJpYWJsZXMgdGhhdCByZXByZXNlbnQgdGhlIGV4dHJlbWVzKS4gQWZ0ZXIgY29ycmVsYXRpb24gYW5hbHlzaXMsIHdlJ3JlIGxlZnQgd2l0aCBCSU81LCBCSU82LCBCSU8xNCwgQklPMTcuCmBgYHtyfQojIFBDQSBvZiBiYWNrZ3JvdW5kIGUtc3BhY2UuIFJlc3VsdGluZyBsaXN0IGlzIGEgY29ycmVsYXRpb24gaGVhdG1hcCAoY29yX2hlYXRtYXApLCBhIHRpYmJsZSBvZiB0aGUgcmFzdGVycyB3aXRoIGNvcnJlbGF0aW9uID4gdGhlIGN1dG9mZiAoZGVmYXVsdCBpcyAwLjc1KSwgYW5kIGEgdGliYmxlIG9mIGFsbCBwYWlyd2lzZSBjb3JyZWxhdGlvbnMKYWp1Y19wY2EgPC0gcmFzdGVyX2NvcnJlbGF0aW9uKHJhc3Rlcl9zdGFjayA9IGFqdWNfYmdfZW52KQphanVjX3BjYSRjb3JfaGVhdG1hcAphanVjX3BjYSR0b3BfY29yICU+JSBrbml0cjo6a2FibGUoKQoKZ2dzYXZlKCJhanVjX3BjYV9jb3JyLnBuZyIsCiAgICAgICBwbG90ID0gYWp1Y19wY2EkY29yX2hlYXRtYXAsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgd3JpdGUgY29ycmVsYXRpb24gZGF0YSBmcmFtZSB0byBmaWxlCnJlYWRyOjp3cml0ZV9jc3YoYWp1Y19wY2EkdG9wX2NvciwgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y190b3BfY29yLmNzdiIpKQoKYGBgCgoKUmVwZWF0IHRoZSBhbmFseXNpcyB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7cn0Kd19hanVjIDwtIHJhc3Rlcjo6c3Vic2V0KHcsIGMoImJpbzUiLCAiYmlvNiIsICJiaW8xNCIsICJiaW8xNyIpKQoKI2dldCBiYWNrZ3JvdW5kIGVudid0IGZvciB0aGUgc3BlY2llcwphanVjX2JnX2Vudl9zdWJzZXQgPC0gYmdfZW52X2Nyb3AoYXN0ZV9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImp1Y3VuZHVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQgPSB3X2FqdWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIgPSAwLjUpCgojZW5mYSBmb3IgdGhlIHNleHVhbCBzcGVjaWVzCmFqdWNfc2V4dWFsX2VuZmFfc3Vic2V0IDwtIGVuZmFfY2FsY19mdW4obG9jcyA9IGFzdGVfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAianVjdW5kdW0iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBhanVjX2JnX2Vudl9zdWJzZXQpCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwphanVjX2FzZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gYXN0ZV9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAianVjdW5kdW0iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBhanVjX2JnX2Vudl9zdWJzZXQpCgojIHdyaXRlIG1hcmdpbmFsaXR5IHNjb3JlcyB0byBjc3YKcmVhZHI6OndyaXRlX2NzdigKICBhanVjX2FzZXh1YWxfZW5mYV9zdWJzZXQkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhanVjX3N1YnNldF9hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgYWp1Y19zZXh1YWxfZW5mYV9zdWJzZXQkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhanVjX3N1YnNldF9zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKIyBwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKYWp1Y19zdWJzZXRfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gYWp1Y19zZXh1YWxfZW5mYV9zdWJzZXQkbSwKICAgIGFzZXhfbWFyZyA9IGFqdWNfYXNleHVhbF9lbmZhX3N1YnNldCRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQXN0ZWxpYXBoYXNtYSBqdWN1bmR1bSIKICApCgphanVjX3N1YnNldF9tYXJnaW5hbGl0eQoKZ2dzYXZlKCJhanVjX3N1YnNldF9tYXJnaW5hbGl0eS5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfc3Vic2V0X21hcmdpbmFsaXR5LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgoKCmBgYAoKClZpc3VhbGl6ZSB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojIGFjY2VzcyB0aGUgcmVsZXZhbnQgdmFsdWVzIGZvciBwbG90dGluZwphanVjX2FzZXh1YWxfZGZfc3Vic2V0IDwtIGFqdWNfYXNleHVhbF9lbmZhX3N1YnNldCRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IGFqdWNfYXNleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgYWp1Y19hc2V4dWFsX2RmX3N1YnNldCwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhanVjX2FzZXh1YWxfZGZfc3Vic2V0LmNzdiIpCikKCgphanVjX3NleHVhbF9kZl9zdWJzZXQgPC0gYWp1Y19zZXh1YWxfZW5mYV9zdWJzZXQkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBhanVjX3NleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgYWp1Y19zZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFqdWNfc2V4dWFsX2RmX3N1YnNldC5jc3YiKQopCgojIGFzZXh1YWwKYWp1Y19zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChhanVjX2FzZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgiYWp1Y19zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBhanVjX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyBzZXh1YWwKYWp1Y19zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KGFqdWNfc2V4dWFsX2RmX3N1YnNldCwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiU2V4dWFsIikKCmdnc2F2ZSgiYWp1Y19zdWJzZXRfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojIGFzZXh1YWwKaGlzdChhanVjX2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJhanVjX3N1YnNldF9hc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChhanVjX2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgoKIyBzZXh1YWwKaGlzdChhanVjX3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiYWp1Y19zdWJzZXRfc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChhanVjX3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCmFqdWNfc3Vic2V0X3RvdGFsX3BjYSA8LSB0b3RhbF9jbGltYXRlX3BjYV9wbG90KGJnX2VudiA9IGFqdWNfYmdfZW52X3N1YnNldCwgbG9jcyA9IGFzdGVfbG9jLCBnZW51cyA9ICJBc3RlbGlhcGhhc21hIiwgc3BlY2llcyA9ICJqdWN1bmR1bSIpCgpnZ3NhdmUoImFqdWNfc3Vic2V0X3RvdGFsX3BjYS5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfc3Vic2V0X3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyBzYXZlIGVuZmEgb2JqZWN0cyBhbmQgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgZW52aXJvbm1lbnQuIFRoZXkgdGFrZSB1cCBhIGxvdCBvZiBtZW1vcnkuCnNhdmVSRFMoYWp1Y19zZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgImFqdWNfc2V4dWFsX2VuZmEuUkRTIikpCnJtKGFqdWNfc2V4dWFsX2VuZmEpCgpzYXZlUkRTKGFqdWNfYXNleHVhbF9lbmZhLCBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAiYWp1Y19hc2V4dWFsX2VuZmEuUkRTIikpCnJtKGFqdWNfYXNleHVhbF9lbmZhKQoKc2F2ZVJEUyhhanVjX3NleHVhbF9lbmZhX3N1YnNldCwKICAgICAgICBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAiYWp1Y19zdWJzZXRfc2V4dWFsX2VuZmEuUkRTIikpCnJtKGFqdWNfc2V4dWFsX2VuZmFfc3Vic2V0KQoKc2F2ZVJEUyhhanVjX2FzZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgImFqdWNfc3Vic2V0X2FzZXh1YWxfZW5mYS5SRFMiKSkKcm0oYWp1Y19hc2V4dWFsX2VuZmFfc3Vic2V0KQpgYGAKCiMjIyMgU3RhYmlsaXR5CgpXZSdyZSBhbHNvIGludGVyZXN0ZWQgaW4gc2VlaW5nIGlmIGFzZXh1YWwgcG9wdWxhdGlvbnMgbGl2ZSBpbiBtb3JlIHVuc3RhYmxlIGNsaW1hdGljIGFyZWFzIHJlbGF0aXZlIHRvIHNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyfQphanVjX2xvY3NfYXNleHVhbCA8LSBhanVjX2xvYyAlPiUgCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSwgc2VwID0gIl8iKSkgJT4lIAogIGZpbHRlcihyZXByb2R1Y3RpdmVfbW9kZSA9PSAiYXNleHVhbCIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCmFqdWNfbG9jc19zZXh1YWwgPC0gYWp1Y19sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gInNleHVhbCIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCnByZWNpcF9hc2V4dWFsX2FqdWMgPC0gcmFzdGVyOjpleHRyYWN0KHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBhc3RlX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnByZWNpcF9zZXh1YWxfYWp1YyA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGFzdGVfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnByZWNpcF9kZl9hanVjIDwtIGJpbmRfcm93cyhwcmVjaXBfYXNleHVhbF9hanVjLCBwcmVjaXBfc2V4dWFsX2FqdWMpCgpyZWFkcjo6d3JpdGVfY3N2KHByZWNpcF9kZl9hanVjLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhanVjX3ByZWNpcF9zdGFiaWxpdHlfZGYuY3N2IikpCgphanVjX3ByZWNpcF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHByZWNpcF9kZl9hanVjLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gcHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmFqdWNfcHJlY2lwX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoImFqdWNfcHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfcHJlY2lwX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgp0ZW1wX2FzZXh1YWxfYWp1YyA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBhc3RlX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgp0ZW1wX3NleHVhbF9hanVjIDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGFzdGVfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmX2FqdWMgPC0gYmluZF9yb3dzKHRlbXBfYXNleHVhbF9hanVjLCB0ZW1wX3NleHVhbF9hanVjKQoKcmVhZHI6OndyaXRlX2Nzdih0ZW1wX2RmX2FqdWMsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFqdWNfdGVtcF9zdGFiaWxpdHlfZGYuY3N2IikpCgphanVjX3RlbXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSB0ZW1wX2RmX2FqdWMsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmFqdWNfdGVtcF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJhanVjX3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBhanVjX3RlbXBfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCm92ZXJhbGxfYXNleHVhbF9hanVjIDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGFzdGVfbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCm92ZXJhbGxfc2V4dWFsX2FqdWMgPC0gcmFzdGVyOjpleHRyYWN0KG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgYXN0ZV9sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCm92ZXJhbGxfZGZfYWp1YyA8LSBiaW5kX3Jvd3Mob3ZlcmFsbF9hc2V4dWFsX2FqdWMsIG92ZXJhbGxfc2V4dWFsX2FqdWMpCgpyZWFkcjo6d3JpdGVfY3N2KG92ZXJhbGxfZGZfYWp1YywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19vdmVyYWxsX3N0YWJpbGl0eV9kZi5jc3YiKSkKCmFqdWNfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IG92ZXJhbGxfZGZfYWp1YywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKYWp1Y19vdmVyYWxsX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoImFqdWNfb3ZlcmFsbF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBhanVjX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmBgYAoKIyMjIyBTZWFzb25hbGl0eQpgYGB7cn0Kc2Vhc19wcmVjaXBfYXNleHVhbF9hanVjIDwtIHJhc3Rlcjo6ZXh0cmFjdCh3JGJpbzE1LCBhanVjX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zZWFzb25hbGl0eSIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpzZWFzX3ByZWNpcF9zZXh1YWxfYWp1YyA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW8xNSwgYWp1Y19sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zZWFzb25hbGl0eSIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnNlYXNfcHJlY2lwX2RmX2FqdWMgPC0gYmluZF9yb3dzKHNlYXNfcHJlY2lwX2FzZXh1YWxfYWp1Yywgc2Vhc19wcmVjaXBfc2V4dWFsX2FqdWMpCgpyZWFkcjo6d3JpdGVfY3N2KHNlYXNfcHJlY2lwX2RmX2FqdWMsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFqdWNfcHJlY2lwX3NlYXNvbmFsaXR5X2RmLmNzdiIpKQoKYWp1Y19wcmVjaXBfc2Vhc29uYWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHNlYXNfcHJlY2lwX2RmX2FqdWMsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBwcmVjaXBfc2Vhc29uYWxpdHksIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmFqdWNfcHJlY2lwX3NlYXNvbmFsaXR5X3Bsb3QKCmdnc2F2ZSgKICAiYWp1Y19wcmVjaXBfc2Vhc29uYWxpdHkucG5nIiwKICBwbG90ID0gYWp1Y19wcmVjaXBfc2Vhc29uYWxpdHlfcGxvdCwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKCnNlYXNfdGVtcF9hc2V4dWFsX2FqdWMgPC0gcmFzdGVyOjpleHRyYWN0KHckYmlvNCwgYWp1Y19sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnNlYXNfdGVtcF9zZXh1YWxfYWp1YyA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW80LCBhanVjX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zZWFzb25hbGl0eSIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnNlYXNfdGVtcF9kZl9hanVjIDwtIGJpbmRfcm93cyhzZWFzX3RlbXBfYXNleHVhbF9hanVjLCBzZWFzX3RlbXBfc2V4dWFsX2FqdWMpCgpyZWFkcjo6d3JpdGVfY3N2KHNlYXNfdGVtcF9kZl9hanVjLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhanVjX3RlbXBfc2Vhc29uYWxpdHlfZGYuY3N2IikpCgphanVjX3RlbXBfc2Vhc29uYWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHNlYXNfdGVtcF9kZl9hanVjLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gdGVtcF9zZWFzb25hbGl0eSwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKYWp1Y190ZW1wX3NlYXNvbmFsaXR5X3Bsb3QKCmdnc2F2ZSgKICAiYWp1Y190ZW1wX3NlYXNvbmFsaXR5LnBuZyIsCiAgcGxvdCA9IGFqdWNfdGVtcF9zZWFzb25hbGl0eV9wbG90LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQpgYGAKCiMjIyMgTW92ZSBvdXRwdXQKUHV0IGFsbCBvdXRwdXQgaW50byBzcGVjaWVzLXNwZWNpZmljIHN1YmZvbGRlcnMuCmBgYHtyIHJlc3VsdHM9ImhpZGUifQphanVjX291dF9pbnRfcGF0aCA8LSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFzdGVsaWFwaGFzbWFfanVjdW5kdW0iKQphanVjX291dF9wbG90X3BhdGggPC0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImFzdGVsaWFwaGFzbWFfanVjdW5kdW0iKQphanVjX291dF9zcHJlYWRfcGF0aCA8LSBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhc3RlbGlhcGhhc21hX2p1Y3VuZHVtIikKYWp1Y19vdXRfb2JqX3BhdGggPC0gZmlsZS5wYXRoKG9ial9wYXRoLCAiYXN0ZWxpYXBoYXNtYV9qdWN1bmR1bSIpCgojIG1vdmUgaW50ZXJhY3RpdmUKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBpbnRlcmFjdGl2ZV9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhanVjX291dF9pbnRfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiYWp1YyIpCgptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gYWp1Y19vdXRfcGxvdF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJhanVjIikKCiMgbW92ZSBzcHJlYWRzaGVldHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBzcHJlYWRfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gYWp1Y19vdXRfc3ByZWFkX3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gImFqdWMiKQoKIyBtb3ZlIG9iamVjdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBvYmpfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gYWp1Y19vdXRfb2JqX3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gImFqdWMiKQpgYGAKCiMjIyBDbGl0YXJjaHVzIGhvb2tlcmkKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnN1bW1hcnlfbGlzdF9jaG9vIDwtIHNwZWNpZXNfcGNhX2Z1bihsb2NfY2xpbSwgZ2VudXMgPSAiY2xpdGFyY2h1cyIsIHNwZWNpZXMgPSAiaG9va2VyaSIpCmNob29fcGxvdCA8LSBwbG90X2NsaW1fcGNhKHN1bW1hcnlfbGlzdF9jaG9vJGxvY19jbGltLCBzdW1tYXJ5X2xpc3RfY2hvbyRzdW1tYXJ5X3BjYSwgZmFjdG9yID0gInJlcHJvZHVjdGl2ZV9tb2RlIikKY2hvb19wbG90CgoKaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQoY2hvb19wbG90LCBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImNob29fcGNhLmh0bWwiKSwgc2VsZmNvbnRhaW5lZCA9IFRSVUUpCgojZmlsdGVyIGxvY2FsaXRpZXMgZm9yIHRoZSBmb2NhbCBnZW51cwpjaG9vX2xvYyA8LSBsb2MgJT4lIAogIGZpbHRlcihnZW51cyA9PSAiY2xpdGFyY2h1cyIpCiAgCiN1c2Ugc291cmNlZCBwbG90X2xvY3NfbGVhZmxldCBzY3JpcHQgdG8gcGxvdCBsb2NhbGl0aWVzCmNob29fbWFwIDwtIHBsb3RfbG9jc19sZWFmbGV0KGNob29fbG9jLCAicmVwcm9kdWN0aXZlX21vZGUiKQoKY2hvb19tYXAKCiMgc2F2ZSB0aGUgbWFwCgptYXB2aWV3OjptYXBzaG90KAogIGNob29fbWFwLAogIHVybCA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiY2hvb19tYXAuaHRtbCIpLAogIGZpbGUgPSBwYXN0ZTAoZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJjaG9vX21hcC5wZGYiKSkKKQoKYGBgCgoKYGBge3J9CnN1bW1hcnlfbGlzdF9jaG9vJHN1bW1hcnlfcGNhCmxvYWRpbmdzX2Nob28gPC0gc3VtbWFyeV9saXN0X2Nob28kc3VtbWFyeV9wY2Ekcm90YXRpb24Ka25pdHI6OmthYmxlKHJvdW5kKGxvYWRpbmdzX2Nob29bLDE6M10sMykpICNUYWJsZSBvZiBsb2FkaW5nIHNjb3JlcyBmb3IgdGhlIGZpcnN0IDMgUENzLiAKYGBgCgojIyMjIEVORkEKCk5vdyBJJ20gZ29pbmcgdG8gcGVyZm9ybSBlbnZpcm9ubWVudGFsIG5pY2hlIGZhY3RvciBhbmFseXNpcyB3aXRoIHNleHVhbCBhbmQgYXNleHVhbCBwb3B1bGF0aW9ucyB3aXRoaW4gdGhlIHNwZWNpZXMuCmBgYHtyIGNhY2hlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgojZ2V0IGJhY2tncm91bmQgZW52J3QgZm9yIHRoZSBzcGVjaWVzCmNob29fYmdfZW52IDwtIGJnX2Vudl9jcm9wKAogIGNob29fbG9jLAogIHNwZWNpZXMgPSAiaG9va2VyaSIsCiAgZW52aXJvbm1lbnQgPSB3LAogIGJ1ZmZlciA9IDAuNQopCgojZW5mYSBmb3IgdGhlIHNleHVhbCBzcGVjaWVzCmNob29fc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bigKICBsb2NzID0gY2hvb19sb2MsCiAgc3BlY2llcyA9ICJob29rZXJpIiwKICByZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiLAogIG1hc2tfcmFzdGVyID0gY2hvb19iZ19lbnYKKQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKY2hvb19hc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bigKICBsb2NzID0gY2hvb19sb2MsCiAgc3BlY2llcyA9ICJob29rZXJpIiwKICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwKICBtYXNrX3Jhc3RlciA9IGNob29fYmdfZW52CikKCiMgd3JpdGUgc2NvcmVzIHRvIGNzdnMKcmVhZHI6OndyaXRlX2NzdigKICBjaG9vX2FzZXh1YWxfZW5mYSRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fYXNleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgpyZWFkcjo6d3JpdGVfY3N2KAogIGNob29fc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjaG9vX3NleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgojcGxvdCB0aGUgbWFyZ2luYWxpdHkgc2NvcmVzCmNob29fbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gY2hvb19zZXh1YWxfZW5mYSRtLAogICAgYXNleF9tYXJnID0gY2hvb19hc2V4dWFsX2VuZmEkbSwKICAgIGZ1bGxfc3BlY2llc19uYW1lID0gIkNsaXRhcmNodXMgaG9va2VyaSIKICApCgpjaG9vX21hcmdpbmFsaXR5CgpnZ3NhdmUoCiAgImNob29fbWFyZ2luYWxpdHlfbG9sbGlwb3AucG5nIiwKICBwbG90ID0gY2hvb19tYXJnaW5hbGl0eSwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKYGBgCgpBIGNvdXBsZSBkaWZmZXJlbnQgd2F5cyB0byB2aXN1YWxpemUgdGhlIGVudmlyb25tZW50YWwgdmFyaWF0aW9uLiAxKSBTY2F0dGVycGxvdCB2aXN1YWxpemF0aW9ucyBvZiBtYXJnaW5hbGl0eSB2cyBheGlzIDEgb2YgdGhlIHNwZWNpYWxpemF0aW9uIHdpdGggdGhlIGxhYmVscyByZW1vdmVkICh0aGV5IG1ha2UgdGhpbmdzIGluZGlzY2VybmFibGUpLiBSZWQgPSBvY2N1cGllZCBlLXNwYWNlLiBHcmF5ID0gQmFja2dyb3VuZCBlLXNwYWNlLiAyKSBFTkZBIGhpc3RvZ3JhbSB2aXN1YWxpemF0aW9ucyBvZiBtYXJnaW5hbGl0eSBhbmQgc3BlY2lhbGl6YXRpb24gYXhlcy4gMykgUENBIG9mIHRvdGFsIGUtc3BhY2Ugd2l0aCBjb2xvcnMgY29ycmVzcG9uZGluZyB0byBzZXh1YWwgdnMuIGFzZXh1YWwgcG9wdWxhdGlvbnMuIApgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyMjIDEpIEVORkEgc2NhdHRlcnBsb3QKI2FjY2VzcyB0aGUgcmVsZXZhbnQgdmFsdWVzIGZvciBwbG90dGluZwpjaG9vX2FzZXh1YWxfZGYgPC0gY2hvb19hc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBjaG9vX2FzZXh1YWxfZW5mYSRwcikKCnJlYWRyOjp3cml0ZV9jc3YoY2hvb19hc2V4dWFsX2RmLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjaG9vX2FzZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgpjaG9vX3NleHVhbF9kZiA8LSBjaG9vX3NleHVhbF9lbmZhJGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gY2hvb19zZXh1YWxfZW5mYSRwcikKCnJlYWRyOjp3cml0ZV9jc3YoY2hvb19zZXh1YWxfZGYsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fc2V4dWFsX21hcmdpbmFsaXR5X2RmLmNzdiIpKQoKIyBhc2V4dWFsCmNob29fZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChjaG9vX2FzZXh1YWxfZGYsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIkFzZXh1YWwiKQoKZ2dzYXZlKCJjaG9vX2VuZmFfc3BlY19hc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gY2hvb19lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKI3NleHVhbApjaG9vX2VuZmFfc3BlY19zZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChjaG9vX3NleHVhbF9kZiwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiU2V4dWFsIikKCmdnc2F2ZSgiY2hvb19lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gY2hvb19lbmZhX3NwZWNfc2V4dWFsLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIyMgMikgRU5GQSBoaXN0b2dyYW0KI2FzZXh1YWwKaGlzdChjaG9vX2FzZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImNob29fYXNleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QoY2hvb19hc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgojc2V4dWFsCmhpc3QoY2hvb19zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiY2hvb19zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGNob29fc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiMjIyAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZQpjaG9vX3RvdGFsX3BjYSA8LSB0b3RhbF9jbGltYXRlX3BjYV9wbG90KGJnX2VudiA9IGNob29fYmdfZW52LCBsb2NzID0gY2hvb19sb2MsIGdlbnVzID0gIkNsaXRhcmNodXMiLCBzcGVjaWVzID0gImhvb2tlcmkiKQoKY2hvb190b3RhbF9wY2EKCmdnc2F2ZSgiY2hvb190b3RhbF9wY2EucG5nIiwKICAgICAgIHBsb3QgPSBjaG9vX3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgojIyMjIyBFTkZBIFJlZHVjZWQKClRyeWluZyBvdXQgYSByZXBlYXQgb2YgdGhlIGFuYWx5c2VzIHdpdGggcmVkdWNlZCBlbnZpcm9ubWVudGFsIHNwYWNlLgpQcmlvcml0aXppbmcgdmFyaWFibGVzIHRoYXQgd2lsbCBsaW1pdCB0aGVpciBkaXN0cmlidXRpb24gKGkuZS4gdmFyaWFibGVzIHRoYXQgcmVwcmVzZW50IHRoZSBleHRyZW1lcykuIEFmdGVyIGNvcnJlbGF0aW9uIGFuYWx5c2lzLCB3ZSdyZSBsZWZ0IHdpdGggQklPOCwgQklPMTEsIEJJTzE1LCBCSU8xNy4gCmBgYHtyfQojIFBDQSBvZiBiYWNrZ3JvdW5kIGUtc3BhY2UuIFJlc3VsdGluZyBsaXN0IGlzIGEgY29ycmVsYXRpb24gaGVhdG1hcCAoY29yX2hlYXRtYXApLCBhIHRpYmJsZSBvZiB0aGUgcmFzdGVycyB3aXRoIGNvcnJlbGF0aW9uID4gdGhlIGN1dG9mZiAoZGVmYXVsdCBpcyAwLjc1KSwgYW5kIGEgdGliYmxlIG9mIGFsbCBwYWlyd2lzZSBjb3JyZWxhdGlvbnMKY2hvb19wY2EgPC0gcmFzdGVyX2NvcnJlbGF0aW9uKHJhc3Rlcl9zdGFjayA9IGNob29fYmdfZW52KQpjaG9vX3BjYSRjb3JfaGVhdG1hcApjaG9vX3BjYSR0b3BfY29yICU+JSBrbml0cjo6a2FibGUoKQoKZ2dzYXZlKCJjaG9vX3BjYV9jb3JyLnBuZyIsCiAgICAgICBwbG90ID0gY2hvb19wY2EkY29yX2hlYXRtYXAsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgd3JpdGUgY29ycmVsYXRpb24gZGF0YSBmcmFtZSB0byBmaWxlCnJlYWRyOjp3cml0ZV9jc3YoY2hvb19wY2EkdG9wX2NvciwgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiY2hvb190b3BfY29yLmNzdiIpKQoKYGBgCgpSZXBlYXQgdGhlIGFuYWx5c2lzIHdpdGggdGhlIHJlZHVjZWQgZGF0YSBzZXQuCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CndfY2hvbyA8LSByYXN0ZXI6OnN1YnNldCh3LCBjKCJiaW84IiwgImJpbzExIiwgImJpbzE1IiwgImJpbzE3IikpCgojZ2V0IGJhY2tncm91bmQgZW52J3QgZm9yIHRoZSBzcGVjaWVzCmNob29fYmdfZW52X3N1YnNldCA8LSBiZ19lbnZfY3JvcChjaG9vX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiaG9va2VyaSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50ID0gd19jaG9vLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gMC41KQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwpjaG9vX3NleHVhbF9lbmZhX3N1YnNldCA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBjaG9vX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImhvb2tlcmkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBjaG9vX2JnX2Vudl9zdWJzZXQpCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwpjaG9vX2FzZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gY2hvb19sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiaG9va2VyaSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IGNob29fYmdfZW52X3N1YnNldCkKCiMgd3JpdGUgbWFyZ2luYWxpdHkgc2NvcmVzIHRvIGNzdgpyZWFkcjo6d3JpdGVfY3N2KAogIGNob29fYXNleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fc3Vic2V0X2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICBjaG9vX3NleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fc3Vic2V0X3NleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgojIHBsb3QgdGhlIG1hcmdpbmFsaXR5IHNjb3JlcwpjaG9vX3N1YnNldF9tYXJnaW5hbGl0eSA8LQogIG1hcmdpbmFsaXR5X2xvbGxpcG9wKAogICAgc2V4X21hcmcgPSBjaG9vX3NleHVhbF9lbmZhX3N1YnNldCRtLAogICAgYXNleF9tYXJnID0gY2hvb19hc2V4dWFsX2VuZmFfc3Vic2V0JG0sCiAgICBmdWxsX3NwZWNpZXNfbmFtZSA9ICJDbGl0YXJjaHVzIGhvb2tlcmkiCiAgKQoKY2hvb19zdWJzZXRfbWFyZ2luYWxpdHkKCmdnc2F2ZSgiY2hvb19zdWJzZXRfbWFyZ2luYWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBjaG9vX3N1YnNldF9tYXJnaW5hbGl0eSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgoKVmlzdWFsaXplIHdpdGggdGhlIHJlZHVjZWQgZGF0YSBzZXQuCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiMgYWNjZXNzIHRoZSByZWxldmFudCB2YWx1ZXMgZm9yIHBsb3R0aW5nCmNob29fYXNleHVhbF9kZl9zdWJzZXQgPC0gY2hvb19hc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gY2hvb19hc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICBjaG9vX2FzZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fYXNleHVhbF9kZl9zdWJzZXQuY3N2IikKKQoKCmNob29fc2V4dWFsX2RmX3N1YnNldCA8LSBjaG9vX3NleHVhbF9lbmZhX3N1YnNldCRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IGNob29fc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICBjaG9vX3NleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiY2hvb19zZXh1YWxfZGZfc3Vic2V0LmNzdiIpCikKCiMgYXNleHVhbApjaG9vX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbCA8LSBlbmZhX2hleF9wbG90KGNob29fYXNleHVhbF9kZl9zdWJzZXQsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIkFzZXh1YWwiKQoKZ2dzYXZlKCJjaG9vX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbC5wbmciLAogICAgICAgcGxvdCA9IGNob29fc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNleHVhbApjaG9vX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QoY2hvb19zZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJTZXh1YWwiKQoKZ2dzYXZlKCJjaG9vX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gY2hvb19zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiMgYXNleHVhbApoaXN0KGNob29fYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImNob29fc3Vic2V0X2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGNob29fYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCgojIHNleHVhbApoaXN0KGNob29fc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJjaG9vX3N1YnNldF9zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGNob29fc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgojIyMgMykgUENBIG9mIHRvdGFsIGUtc3BhY2UKY2hvb19zdWJzZXRfdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gY2hvb19iZ19lbnZfc3Vic2V0LCBsb2NzID0gY2hvb19sb2MsIGdlbnVzID0gIkNsaXRhcmNodXMiLCBzcGVjaWVzID0gImhvb2tlcmkiKQoKY2hvb19zdWJzZXRfdG90YWxfcGNhCgpnZ3NhdmUoImNob29fc3Vic2V0X3RvdGFsX3BjYS5wbmciLAogICAgICAgcGxvdCA9IGNob29fc3Vic2V0X3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyBzYXZlIGVuZmEgb2JqZWN0cyBhbmQgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgZW52aXJvbm1lbnQuIFRoZXkgdGFrZSB1cCBhIGxvdCBvZiBtZW1vcnkuCnNhdmVSRFMoY2hvb19zZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgImNob29fc2V4dWFsX2VuZmEuUkRTIikpCnJtKGNob29fc2V4dWFsX2VuZmEpCgpzYXZlUkRTKGNob29fYXNleHVhbF9lbmZhLCBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAiY2hvb19hc2V4dWFsX2VuZmEuUkRTIikpCnJtKGNob29fYXNleHVhbF9lbmZhKQoKc2F2ZVJEUyhjaG9vX3NleHVhbF9lbmZhX3N1YnNldCwKICAgICAgICBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAiY2hvb19zdWJzZXRfc2V4dWFsX2VuZmEuUkRTIikpCnJtKGNob29fc2V4dWFsX2VuZmFfc3Vic2V0KQoKc2F2ZVJEUyhjaG9vX2FzZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgImNob29fc3Vic2V0X2FzZXh1YWxfZW5mYS5SRFMiKSkKcm0oY2hvb19hc2V4dWFsX2VuZmFfc3Vic2V0KQpgYGAKCiMjIyMgU3RhYmlsaXR5CgpXZSdyZSBhbHNvIGludGVyZXN0ZWQgaW4gc2VlaW5nIGlmIGFzZXh1YWwgcG9wdWxhdGlvbnMgbGl2ZSBpbiBtb3JlIHVuc3RhYmxlIGNsaW1hdGljIGFyZWFzIHJlbGF0aXZlIHRvIHNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmNob29fbG9jc19hc2V4dWFsIDwtIGNob29fbG9jICU+JSAKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlLCBzZXAgPSAiXyIpKSAlPiUgCiAgZmlsdGVyKHJlcHJvZHVjdGl2ZV9tb2RlID09ICJhc2V4dWFsIiwKICAgICAgICAgIWR1cGxpY2F0ZWQobGF0X2xvbmcpKSAlPiUgCiAgZHBseXI6OnNlbGVjdChsb25naXR1ZGUsIGxhdGl0dWRlKQoKY2hvb19sb2NzX3NleHVhbCA8LSBjaG9vX2xvYyAlPiUgCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSwgc2VwID0gIl8iKSkgJT4lIAogIGZpbHRlcihyZXByb2R1Y3RpdmVfbW9kZSA9PSAic2V4dWFsIiwKICAgICAgICAgIWR1cGxpY2F0ZWQobGF0X2xvbmcpKSAlPiUgCiAgZHBseXI6OnNlbGVjdChsb25naXR1ZGUsIGxhdGl0dWRlKQoKcHJlY2lwX2FzZXh1YWxfY2hvbyA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGNob29fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKcHJlY2lwX3NleHVhbF9jaG9vIDwtIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgY2hvb19sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKcHJlY2lwX2RmX2Nob28gPC0gYmluZF9yb3dzKHByZWNpcF9hc2V4dWFsX2Nob28sIHByZWNpcF9zZXh1YWxfY2hvbykKCnJlYWRyOjp3cml0ZV9jc3YocHJlY2lwX2RmX2Nob28sIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fcHJlY2lwX3N0YWJpbGl0eV9kZi5jc3YiKSkKCmNob29fcHJlY2lwX3N0YWJpbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gcHJlY2lwX2RmX2Nob28sIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKY2hvb19wcmVjaXBfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgiY2hvb19wcmVjaXBfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gY2hvb19wcmVjaXBfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCnRlbXBfYXNleHVhbF9jaG9vIDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGNob29fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnRlbXBfc2V4dWFsX2Nob28gPC0gcmFzdGVyOjpleHRyYWN0KHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgY2hvb19sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnRlbXBfZGZfY2hvbyA8LSBiaW5kX3Jvd3ModGVtcF9hc2V4dWFsX2Nob28sIHRlbXBfc2V4dWFsX2Nob28pCgpyZWFkcjo6d3JpdGVfY3N2KHRlbXBfZGZfY2hvbywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiY2hvb190ZW1wX3N0YWJpbGl0eV9kZi5jc3YiKSkKCmNob29fdGVtcF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHRlbXBfZGZfY2hvbywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKY2hvb190ZW1wX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoImNob29fcHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IGNob29fdGVtcF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKb3ZlcmFsbF9hc2V4dWFsX2Nob28gPC0gcmFzdGVyOjpleHRyYWN0KG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgY2hvb19sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKb3ZlcmFsbF9zZXh1YWxfY2hvbyA8LSByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBjaG9vX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKb3ZlcmFsbF9kZl9jaG9vIDwtIGJpbmRfcm93cyhvdmVyYWxsX2FzZXh1YWxfY2hvbywgb3ZlcmFsbF9zZXh1YWxfY2hvbykKCnJlYWRyOjp3cml0ZV9jc3Yob3ZlcmFsbF9kZl9jaG9vLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjaG9vX292ZXJhbGxfc3RhYmlsaXR5X2RmLmNzdiIpKQoKY2hvb19vdmVyYWxsX3N0YWJpbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gb3ZlcmFsbF9kZl9jaG9vLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gb3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpjaG9vX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgiY2hvb19vdmVyYWxsX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IGNob29fb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQpgYGAKCiMjIyMgU2Vhc29uYWxpdHkKYGBge3J9CnNlYXNfcHJlY2lwX2FzZXh1YWxfY2hvbyA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW8xNSwgY2hvb19sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc2Vhc29uYWxpdHkiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKc2Vhc19wcmVjaXBfc2V4dWFsX2Nob28gPC0gcmFzdGVyOjpleHRyYWN0KHckYmlvMTUsIGNob29fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc2Vhc29uYWxpdHkiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpzZWFzX3ByZWNpcF9kZl9jaG9vIDwtIGJpbmRfcm93cyhzZWFzX3ByZWNpcF9hc2V4dWFsX2Nob28sIHNlYXNfcHJlY2lwX3NleHVhbF9jaG9vKQoKcmVhZHI6OndyaXRlX2NzdihzZWFzX3ByZWNpcF9kZl9jaG9vLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjaG9vX3ByZWNpcF9zZWFzb25hbGl0eV9kZi5jc3YiKSkKCmNob29fcHJlY2lwX3NlYXNvbmFsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBzZWFzX3ByZWNpcF9kZl9jaG9vLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gcHJlY2lwX3NlYXNvbmFsaXR5LCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpjaG9vX3ByZWNpcF9zZWFzb25hbGl0eV9wbG90CgpnZ3NhdmUoCiAgImNob29fcHJlY2lwX3NlYXNvbmFsaXR5LnBuZyIsCiAgcGxvdCA9IGNob29fcHJlY2lwX3NlYXNvbmFsaXR5X3Bsb3QsCiAgZGV2aWNlID0gInBuZyIsCiAgcGF0aCA9IHBsb3RfcGF0aCwKICBkcGkgPSAicmV0aW5hIgopCgpzZWFzX3RlbXBfYXNleHVhbF9jaG9vIDwtIHJhc3Rlcjo6ZXh0cmFjdCh3JGJpbzQsIGNob29fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zZWFzb25hbGl0eSIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpzZWFzX3RlbXBfc2V4dWFsX2Nob28gPC0gcmFzdGVyOjpleHRyYWN0KHckYmlvNCwgY2hvb19sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc2Vhc29uYWxpdHkiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpzZWFzX3RlbXBfZGZfY2hvbyA8LSBiaW5kX3Jvd3Moc2Vhc190ZW1wX2FzZXh1YWxfY2hvbywgc2Vhc190ZW1wX3NleHVhbF9jaG9vKQoKcmVhZHI6OndyaXRlX2NzdihzZWFzX3RlbXBfZGZfY2hvbywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiY2hvb190ZW1wX3NlYXNvbmFsaXR5X2RmLmNzdiIpKQoKY2hvb190ZW1wX3NlYXNvbmFsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBzZWFzX3RlbXBfZGZfY2hvbywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHRlbXBfc2Vhc29uYWxpdHksIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmNob29fdGVtcF9zZWFzb25hbGl0eV9wbG90CgpnZ3NhdmUoCiAgImNob29fdGVtcF9zZWFzb25hbGl0eS5wbmciLAogIHBsb3QgPSBjaG9vX3RlbXBfc2Vhc29uYWxpdHlfcGxvdCwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKYGBgCgojIyMjIE1vdmUgb3V0cHV0CgpQdXQgYWxsIG91dHB1dCBpbnRvIHNwZWNpZXMtc3BlY2lmaWMgc3ViZm9sZGVycy4KYGBge3IgcmVzdWx0cz0iaGlkZSJ9CmNob29fb3V0X2ludF9wYXRoIDwtIGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiY2xpdGFyY2h1c19ob29rZXJpIikKY2hvb19vdXRfcGxvdF9wYXRoIDwtIGZpbGUucGF0aChwbG90X3BhdGgsICJjbGl0YXJjaHVzX2hvb2tlcmkiKQpjaG9vX291dF9zcHJlYWRfcGF0aCA8LSBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjbGl0YXJjaHVzX2hvb2tlcmkiKQpjaG9vX291dF9vYmpfcGF0aCA8LSBmaWxlLnBhdGgob2JqX3BhdGgsICJjbGl0YXJjaHVzX2hvb2tlcmkiKQoKIyBtb3ZlIGludGVyYWN0aXZlCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gaW50ZXJhY3RpdmVfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gY2hvb19vdXRfaW50X3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gImNob28iKQojIG1vdmUgcGxvdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBwbG90X3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IGNob29fb3V0X3Bsb3RfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiY2hvbyIpCgojIG1vdmUgc3ByZWFkc2hlZXRzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gc3ByZWFkX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IGNob29fb3V0X3NwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJjaG9vIikKCiMgbW92ZSBvYmplY3RzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gb2JqX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IGNob29fb3V0X29ial9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJjaG9vIikKYGBgCgoKIyMjIE5pdmVhcGhhc21hIGFubnVsYXRhCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1UUlVFfQpzdW1tYXJ5X2xpc3RfbmFubiA8LSBzcGVjaWVzX3BjYV9mdW4obG9jX2NsaW0sIGdlbnVzID0gIm5pdmVhcGhhc21hIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiYW5udWxhdGEiKQpuYW5uX3Bsb3QgPC0gcGxvdF9jbGltX3BjYShzdW1tYXJ5X2xpc3RfbmFubiRsb2NfY2xpbSwgc3VtbWFyeV9saXN0X25hbm4kc3VtbWFyeV9wY2EsIGZhY3RvciA9ICJyZXByb2R1Y3RpdmVfbW9kZSIpCgpuYW5uX3Bsb3QKCiMgc2F2ZSB0aGUgcGxvdCAKaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQobmFubl9wbG90LCBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgIm5hbm5fcGNhLmh0bWwiKSwgc2VsZmNvbnRhaW5lZCA9IFRSVUUpCgojZmlsdGVyIGxvY2FsaXRpZXMgZm9yIHRoZSBmb2NhbCBnZW51cwpuYW5uX2xvYyA8LSBsb2MgJT4lIAogIGZpbHRlcihnZW51cyA9PSAibml2ZWFwaGFzbWEiKQogIAojdXNlIHNvdXJjZWQgcGxvdF9sb2NzX2xlYWZsZXQgc2NyaXB0IHRvIHBsb3QgbG9jYWxpdGllcwpuYW5uX21hcCA8LSBwbG90X2xvY3NfbGVhZmxldChuYW5uX2xvYywgInJlcHJvZHVjdGl2ZV9tb2RlIikKCm5hbm5fbWFwCgojIHNhdmUgdGhlIG1hcAptYXB2aWV3OjptYXBzaG90KG5hbm5fbWFwLCB1cmwgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgIm5hbm5fbWFwLmh0bWwiKSwgZmlsZSA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAibmFubl9tYXAucGRmIikpCgpgYGAKCmBgYHtyfQpzdW1tYXJ5X2xpc3RfbmFubiRzdW1tYXJ5X3BjYQpsb2FkaW5nc19uYW5uIDwtIHN1bW1hcnlfbGlzdF9uYW5uJHN1bW1hcnlfcGNhJHJvdGF0aW9uCmtuaXRyOjprYWJsZShyb3VuZChsb2FkaW5nc19uYW5uWywxOjNdLDMpKSAjVGFibGUgb2YgbG9hZGluZyBzY29yZXMgZm9yIHRoZSBmaXJzdCAzIFBDcy4gCmBgYAoKIyMjIyBFTkZBCgpOb3cgSSdtIGdvaW5nIHRvIHBlcmZvcm0gZW52aXJvbm1lbnRhbCBuaWNoZSBmYWN0b3IgYW5hbHlzaXMgd2l0aCBzZXh1YWwgYW5kIGFzZXh1YWwgcG9wdWxhdGlvbnMgd2l0aGluIHRoZSBzcGVjaWVzLgpgYGB7ciBjYWNoZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIGdldCBiYWNrZ3JvdW5kIGVudid0IGZvciB0aGUgc3BlY2llcwpuYW5uX2JnX2VudiA8LSBiZ19lbnZfY3JvcCgKICBuYW5uX2xvYywKICBzcGVjaWVzID0gImFubnVsYXRhIiwKICBlbnZpcm9ubWVudCA9IHcsCiAgYnVmZmVyID0gMC41CikKCiNlbmZhIGZvciB0aGUgc2V4dWFsIHNwZWNpZXMKbmFubl9zZXh1YWxfZW5mYSA8LSBlbmZhX2NhbGNfZnVuKAogIGxvY3MgPSBuYW5uX2xvYywKICBzcGVjaWVzID0gImFubnVsYXRhIiwKICByZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiLAogIG1hc2tfcmFzdGVyID0gbmFubl9iZ19lbnYKKQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKbmFubl9hc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bigKICBsb2NzID0gbmFubl9sb2MsCiAgc3BlY2llcyA9ICJhbm51bGF0YSIsCiAgcmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIsCiAgbWFza19yYXN0ZXIgPSBuYW5uX2JnX2VudgopCgojIHdyaXRlIHNjb3JlcyB0byBjc3ZzCnJlYWRyOjp3cml0ZV9jc3YoCiAgbmFubl9hc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuYW5uX2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICBuYW5uX3NleHVhbF9lbmZhJG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibmFubl9zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKI3Bsb3QgdGhlIG1hcmdpbmFsaXR5IHNjb3JlcwpuYW5uX21hcmdpbmFsaXR5IDwtCiAgbWFyZ2luYWxpdHlfbG9sbGlwb3AoCiAgICBzZXhfbWFyZyA9IG5hbm5fc2V4dWFsX2VuZmEkbSwKICAgIGFzZXhfbWFyZyA9IG5hbm5fYXNleHVhbF9lbmZhJG0sCiAgICBmdWxsX3NwZWNpZXNfbmFtZSA9ICJOaXZlYXBoYXNtYSBhbm51bGF0YSIKICApCgpuYW5uX21hcmdpbmFsaXR5CgpnZ3NhdmUoCiAgIm5hbm5fbWFyZ2luYWxpdHlfbG9sbGlwb3AucG5nIiwKICBwbG90ID0gbmFubl9tYXJnaW5hbGl0eSwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKYGBgCgoKCkEgY291cGxlIGRpZmZlcmVudCB3YXlzIHRvIHZpc3VhbGl6ZSB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24uIDEpIFNjYXR0ZXJwbG90IHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IHZzIGF4aXMgMSBvZiB0aGUgc3BlY2lhbGl6YXRpb24gd2l0aCB0aGUgbGFiZWxzIHJlbW92ZWQgKHRoZXkgbWFrZSB0aGluZ3MgaW5kaXNjZXJuYWJsZSkuIFJlZCA9IG9jY3VwaWVkIGUtc3BhY2UuIEdyYXkgPSBCYWNrZ3JvdW5kIGUtc3BhY2UuIDIpIEVORkEgaGlzdG9ncmFtIHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IGFuZCBzcGVjaWFsaXphdGlvbiBheGVzLiAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZSB3aXRoIGNvbG9ycyBjb3JyZXNwb25kaW5nIHRvIHNleHVhbCB2cy4gYXNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojYWNjZXNzIHRoZSByZWxldmFudCB2YWx1ZXMgZm9yIHBsb3R0aW5nCm5hbm5fYXNleHVhbF9kZiA8LSBuYW5uX2FzZXh1YWxfZW5mYSRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IG5hbm5fYXNleHVhbF9lbmZhJHByKQoKcmVhZHI6OndyaXRlX2NzdihuYW5uX2FzZXh1YWxfZGYsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5hbm5fYXNleHVhbF9tYXJnaW5hbGl0eV9kZi5jc3YiKSkKCm5hbm5fc2V4dWFsX2RmIDwtIG5hbm5fc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBuYW5uX3NleHVhbF9lbmZhJHByKQoKcmVhZHI6OndyaXRlX2NzdihuYW5uX3NleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibmFubl9zZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgojIGFzZXh1YWwKbmFubl9lbmZhX3NwZWNfYXNleHVhbCA8LSBlbmZhX2hleF9wbG90KG5hbm5fYXNleHVhbF9kZiwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiQXNleHVhbCIpCgpnZ3NhdmUoIm5hbm5fZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBuYW5uX2VuZmFfc3BlY19hc2V4dWFsLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojc2V4dWFsCm5hbm5fZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KG5hbm5fc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJTZXh1YWwiKQoKZ2dzYXZlKCJuYW5uX2VuZmFfc3BlY19zZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBuYW5uX2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojYXNleHVhbApoaXN0KG5hbm5fYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAibmFubl9hc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChuYW5uX2FzZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiNzZXh1YWwKaGlzdChuYW5uX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJuYW5uX3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QobmFubl9zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCm5hbm5fdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gbmFubl9iZ19lbnYsIGxvY3MgPSBuYW5uX2xvYywgZ2VudXMgPSAiTml2ZWFwaGFzbWEiLCBzcGVjaWVzID0gImFubnVsYXRhIikKCm5hbm5fdG90YWxfcGNhCgpnZ3NhdmUoIm5hbm5fdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gbmFubl90b3RhbF9wY2EsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmBgYAoKIyMjIyBFTkZBIFJlZHVjZWQKClRyeWluZyBvdXQgYSByZXBlYXQgb2YgdGhlIGFuYWx5c2VzIHdpdGggcmVkdWNlZCBlbnZpcm9ubWVudGFsIHNwYWNlLgpQcmlvcml0aXppbmcgdmFyaWFibGVzIHRoYXQgd2lsbCBsaW1pdCB0aGVpciBkaXN0cmlidXRpb24gKGkuZS4gdmFyaWFibGVzIHRoYXQgcmVwcmVzZW50IHRoZSBleHRyZW1lcykuIEFmdGVyIGNvcnJlbGF0aW9uIGFuYWx5c2lzLCB3ZSdyZSBsZWZ0IHdpdGggQklPNCwgQklPOCwgQklPOSwgQklPMTEsIEJJTzE1LCBCSU8xNwpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFBDQSBvZiBiYWNrZ3JvdW5kIGUtc3BhY2UuIFJlc3VsdGluZyBsaXN0IGlzIGEgY29ycmVsYXRpb24gaGVhdG1hcCAoY29yX2hlYXRtYXApLCBhIHRpYmJsZSBvZiB0aGUgcmFzdGVycyB3aXRoIGNvcnJlbGF0aW9uID4gdGhlIGN1dG9mZiAoZGVmYXVsdCBpcyAwLjc1KSwgYW5kIGEgdGliYmxlIG9mIGFsbCBwYWlyd2lzZSBjb3JyZWxhdGlvbnMKbmFubl9wY2EgPC0gcmFzdGVyX2NvcnJlbGF0aW9uKHJhc3Rlcl9zdGFjayA9IG5hbm5fYmdfZW52KQpuYW5uX3BjYSRjb3JfaGVhdG1hcApuYW5uX3BjYSR0b3BfY29yICU+JSBrbml0cjo6a2FibGUoKQoKZ2dzYXZlKCJuYW5uX3BjYV9jb3JyLnBuZyIsCiAgICAgICBwbG90ID0gbmFubl9wY2EkY29yX2hlYXRtYXAsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgd3JpdGUgY29ycmVsYXRpb24gZGF0YSBmcmFtZSB0byBmaWxlCnJlYWRyOjp3cml0ZV9jc3YobmFubl9wY2EkdG9wX2NvciwgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibmFubl90b3BfY29yLmNzdiIpKQoKYGBgCgpSZXBlYXQgdGhlIGFuYWx5c2lzIHdpdGggdGhlIHJlZHVjZWQgZGF0YSBzZXQuCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CndfbmFubiA8LSByYXN0ZXI6OnN1YnNldCh3LCBjKCJiaW80IiwgImJpbzgiLCAiYmlvOSIsICJiaW8xMSIsICJiaW8xNSIsICJiaW8xNyIpKQoKI2dldCBiYWNrZ3JvdW5kIGVudid0IGZvciB0aGUgc3BlY2llcwpuYW5uX2JnX2Vudl9zdWJzZXQgPC0gYmdfZW52X2Nyb3AobmFubl9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImFubnVsYXRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQgPSB3X25hbm4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIgPSAwLjUpCgojZW5mYSBmb3IgdGhlIHNleHVhbCBzcGVjaWVzCm5hbm5fc2V4dWFsX2VuZmFfc3Vic2V0IDwtIGVuZmFfY2FsY19mdW4obG9jcyA9IG5hbm5fbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiYW5udWxhdGEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBuYW5uX2JnX2Vudl9zdWJzZXQpCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwpuYW5uX2FzZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gbmFubl9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiYW5udWxhdGEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBuYW5uX2JnX2Vudl9zdWJzZXQpCgojIHdyaXRlIG1hcmdpbmFsaXR5IHNjb3JlcyB0byBjc3YKcmVhZHI6OndyaXRlX2NzdigKICBuYW5uX2FzZXh1YWxfZW5mYV9zdWJzZXQkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuYW5uX3N1YnNldF9hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgbmFubl9zZXh1YWxfZW5mYV9zdWJzZXQkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuYW5uX3N1YnNldF9zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKIyBwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKbmFubl9zdWJzZXRfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gbmFubl9zZXh1YWxfZW5mYV9zdWJzZXQkbSwKICAgIGFzZXhfbWFyZyA9IG5hbm5fYXNleHVhbF9lbmZhX3N1YnNldCRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiTml2ZWFwaGFzbWEgYW5udWxhdGEiCiAgKQoKbmFubl9zdWJzZXRfbWFyZ2luYWxpdHkKCmdnc2F2ZSgibmFubl9zdWJzZXRfbWFyZ2luYWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBuYW5uX3N1YnNldF9tYXJnaW5hbGl0eSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgpWaXN1YWxpemUgd2l0aCB0aGUgcmVkdWNlZCBkYXRhIHNldC4KYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyMjIDEpIEVORkEgc2NhdHRlcnBsb3QKIyBhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKbmFubl9hc2V4dWFsX2RmX3N1YnNldCA8LSBuYW5uX2FzZXh1YWxfZW5mYV9zdWJzZXQkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBuYW5uX2FzZXh1YWxfZW5mYV9zdWJzZXQkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KAogIG5hbm5fYXNleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibmFubl9hc2V4dWFsX2RmX3N1YnNldC5jc3YiKQopCgoKbmFubl9zZXh1YWxfZGZfc3Vic2V0IDwtIG5hbm5fc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gbmFubl9zZXh1YWxfZW5mYV9zdWJzZXQkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KAogIG5hbm5fc2V4dWFsX2RmX3N1YnNldCwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuYW5uX3NleHVhbF9kZl9zdWJzZXQuY3N2IikKKQoKIyBhc2V4dWFsCm5hbm5fc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QobmFubl9hc2V4dWFsX2RmX3N1YnNldCwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiQXNleHVhbCIpCgpnZ3NhdmUoIm5hbm5fc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gbmFubl9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgc2V4dWFsCm5hbm5fc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChuYW5uX3NleHVhbF9kZl9zdWJzZXQsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoIm5hbm5fc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBuYW5uX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIyMgMikgRU5GQSBoaXN0b2dyYW0KIyBhc2V4dWFsCmhpc3QobmFubl9hc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAibmFubl9zdWJzZXRfYXNleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QobmFubl9hc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKCiMgc2V4dWFsCmhpc3QobmFubl9zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgIm5hbm5fc3Vic2V0X3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QobmFubl9zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiMjIyAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZQpuYW5uX3N1YnNldF90b3RhbF9wY2EgPC0gdG90YWxfY2xpbWF0ZV9wY2FfcGxvdChiZ19lbnYgPSBuYW5uX2JnX2Vudl9zdWJzZXQsIGxvY3MgPSBuYW5uX2xvYywgZ2VudXMgPSAiTml2ZWFwaGFzbWEiLCBzcGVjaWVzID0gImFubnVsYXRhIikKCm5hbm5fc3Vic2V0X3RvdGFsX3BjYQoKZ2dzYXZlKCJuYW5uX3N1YnNldF90b3RhbF9wY2EucG5nIiwKICAgICAgIHBsb3QgPSBuYW5uX3N1YnNldF90b3RhbF9wY2EsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgc2F2ZSBlbmZhIG9iamVjdHMgYW5kIHJlbW92ZSB0aGVtIGZyb20gdGhlIGVudmlyb25tZW50LiBUaGV5IHRha2UgdXAgYSBsb3Qgb2YgbWVtb3J5LgpzYXZlUkRTKG5hbm5fc2V4dWFsX2VuZmEsIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJuYW5uX3NleHVhbF9lbmZhLlJEUyIpKQpybShuYW5uX3NleHVhbF9lbmZhKQoKc2F2ZVJEUyhuYW5uX2FzZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgIm5hbm5fYXNleHVhbF9lbmZhLlJEUyIpKQpybShuYW5uX2FzZXh1YWxfZW5mYSkKCnNhdmVSRFMobmFubl9zZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgIm5hbm5fc3Vic2V0X3NleHVhbF9lbmZhLlJEUyIpKQpybShuYW5uX3NleHVhbF9lbmZhX3N1YnNldCkKCnNhdmVSRFMobmFubl9hc2V4dWFsX2VuZmFfc3Vic2V0LAogICAgICAgIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJuYW5uX3N1YnNldF9hc2V4dWFsX2VuZmEuUkRTIikpCnJtKG5hbm5fYXNleHVhbF9lbmZhX3N1YnNldCkKYGBgCgojIyMjIFN0YWJpbGl0eQoKV2UncmUgYWxzbyBpbnRlcmVzdGVkIGluIHNlZWluZyBpZiBhc2V4dWFsIHBvcHVsYXRpb25zIGxpdmUgaW4gbW9yZSB1bnN0YWJsZSBjbGltYXRpYyBhcmVhcyByZWxhdGl2ZSB0byBzZXh1YWwgcG9wdWxhdGlvbnMuIApgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpuYW5uX2xvY3NfYXNleHVhbCA8LSBuYW5uX2xvYyAlPiUgCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSwgc2VwID0gIl8iKSkgJT4lIAogIGZpbHRlcihyZXByb2R1Y3RpdmVfbW9kZSA9PSAiYXNleHVhbCIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCm5hbm5fbG9jc19zZXh1YWwgPC0gbmFubl9sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gInNleHVhbCIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCnByZWNpcF9hc2V4dWFsX25hbm4gPC0gcmFzdGVyOjpleHRyYWN0KHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBuYW5uX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnByZWNpcF9zZXh1YWxfbmFubiA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIG5hbm5fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnByZWNpcF9kZl9uYW5uIDwtIGJpbmRfcm93cyhwcmVjaXBfYXNleHVhbF9uYW5uLCBwcmVjaXBfc2V4dWFsX25hbm4pCgpyZWFkcjo6d3JpdGVfY3N2KHByZWNpcF9kZl9uYW5uLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuYW5uX3ByZWNpcF9zdGFiaWxpdHlfZGYuY3N2IikpCgpuYW5uX3ByZWNpcF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHByZWNpcF9kZl9uYW5uLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gcHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCm5hbm5fcHJlY2lwX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoIm5hbm5fcHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IG5hbm5fcHJlY2lwX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgp0ZW1wX2FzZXh1YWxfbmFubiA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBuYW5uX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgp0ZW1wX3NleHVhbF9uYW5uIDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIG5hbm5fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmX25hbm4gPC0gYmluZF9yb3dzKHRlbXBfYXNleHVhbF9uYW5uLCB0ZW1wX3NleHVhbF9uYW5uKQoKcmVhZHI6OndyaXRlX2Nzdih0ZW1wX2RmX25hbm4sIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5hbm5fdGVtcF9zdGFiaWxpdHlfZGYuY3N2IikpCgpuYW5uX3RlbXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSB0ZW1wX2RmX25hbm4sIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCm5hbm5fdGVtcF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJuYW5uX3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBuYW5uX3RlbXBfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCm92ZXJhbGxfYXNleHVhbF9uYW5uIDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIG5hbm5fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCm92ZXJhbGxfc2V4dWFsX25hbm4gPC0gcmFzdGVyOjpleHRyYWN0KG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgbmFubl9sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCm92ZXJhbGxfZGZfbmFubiA8LSBiaW5kX3Jvd3Mob3ZlcmFsbF9hc2V4dWFsX25hbm4sIG92ZXJhbGxfc2V4dWFsX25hbm4pCgpyZWFkcjo6d3JpdGVfY3N2KG92ZXJhbGxfZGZfbmFubiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibmFubl9vdmVyYWxsX3N0YWJpbGl0eV9kZi5jc3YiKSkKCm5hbm5fb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IG92ZXJhbGxfZGZfbmFubiwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKbmFubl9vdmVyYWxsX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoIm5hbm5fb3ZlcmFsbF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBuYW5uX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKYGBgCgojIyMjIFNlYXNvbmFsaXR5CmBgYHtyfQpzZWFzX3ByZWNpcF9hc2V4dWFsX25hbm4gPC0gcmFzdGVyOjpleHRyYWN0KHckYmlvMTUsIG5hbm5fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnNlYXNfcHJlY2lwX3NleHVhbF9uYW5uIDwtIHJhc3Rlcjo6ZXh0cmFjdCh3JGJpbzE1LCBuYW5uX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKc2Vhc19wcmVjaXBfZGZfbmFubiA8LSBiaW5kX3Jvd3Moc2Vhc19wcmVjaXBfYXNleHVhbF9uYW5uLCBzZWFzX3ByZWNpcF9zZXh1YWxfbmFubikKCnJlYWRyOjp3cml0ZV9jc3Yoc2Vhc19wcmVjaXBfZGZfbmFubiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibmFubl9wcmVjaXBfc2Vhc29uYWxpdHlfZGYuY3N2IikpCgpuYW5uX3ByZWNpcF9zZWFzb25hbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gc2Vhc19wcmVjaXBfZGZfbmFubiwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zZWFzb25hbGl0eSwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKbmFubl9wcmVjaXBfc2Vhc29uYWxpdHlfcGxvdAoKZ2dzYXZlKAogICJuYW5uX3ByZWNpcF9zZWFzb25hbGl0eS5wbmciLAogIHBsb3QgPSBuYW5uX3ByZWNpcF9zZWFzb25hbGl0eV9wbG90LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQoKc2Vhc190ZW1wX2FzZXh1YWxfbmFubiA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW80LCBuYW5uX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc2Vhc29uYWxpdHkiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKc2Vhc190ZW1wX3NleHVhbF9uYW5uIDwtIHJhc3Rlcjo6ZXh0cmFjdCh3JGJpbzQsIG5hbm5fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKc2Vhc190ZW1wX2RmX25hbm4gPC0gYmluZF9yb3dzKHNlYXNfdGVtcF9hc2V4dWFsX25hbm4sIHNlYXNfdGVtcF9zZXh1YWxfbmFubikKCnJlYWRyOjp3cml0ZV9jc3Yoc2Vhc190ZW1wX2RmX25hbm4sIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5hbm5fdGVtcF9zZWFzb25hbGl0eV9kZi5jc3YiKSkKCm5hbm5fdGVtcF9zZWFzb25hbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gc2Vhc190ZW1wX2RmX25hbm4sIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3NlYXNvbmFsaXR5LCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpuYW5uX3RlbXBfc2Vhc29uYWxpdHlfcGxvdAoKZ2dzYXZlKAogICJuYW5uX3RlbXBfc2Vhc29uYWxpdHkucG5nIiwKICBwbG90ID0gbmFubl90ZW1wX3NlYXNvbmFsaXR5X3Bsb3QsCiAgZGV2aWNlID0gInBuZyIsCiAgcGF0aCA9IHBsb3RfcGF0aCwKICBkcGkgPSAicmV0aW5hIgopCmBgYAojIyMjIE1vdmUgb3V0cHV0CgpQdXQgYWxsIG91dHB1dCBpbnRvIHNwZWNpZXMtc3BlY2lmaWMgc3ViZm9sZGVycy4KYGBge3IgcmVzdWx0cz0iaGlkZSJ9Cm5hbm5fb3V0X2ludF9wYXRoIDwtIGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAibml2ZWFwaGFzbWFfYW5udWxhdGEiKQpuYW5uX291dF9wbG90X3BhdGggPC0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgIm5pdmVhcGhhc21hX2FubnVsYXRhIikKbmFubl9vdXRfc3ByZWFkX3BhdGggPC0gZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibml2ZWFwaGFzbWFfYW5udWxhdGEiKQpuYW5uX291dF9vYmpfcGF0aCA8LSBmaWxlLnBhdGgob2JqX3BhdGgsICJuaXZlYXBoYXNtYV9hbm51bGF0YSIpCgojIG1vdmUgaW50ZXJhY3RpdmUKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBpbnRlcmFjdGl2ZV9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBuYW5uX291dF9pbnRfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAibmFubiIpCiMgbW92ZSBwbG90cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gbmFubl9vdXRfcGxvdF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJuYW5uIikKCiMgbW92ZSBzcHJlYWRzaGVldHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBzcHJlYWRfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gbmFubl9vdXRfc3ByZWFkX3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gIm5hbm4iKQoKIyBtb3ZlIG9iamVjdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBvYmpfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gbmFubl9vdXRfb2JqX3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gIm5hbm4iKQpgYGAKCgpgYGB7cn0Kc3VtbWFyeV9saXN0X3RlY3Qkc3VtbWFyeV9wY2EKbG9hZGluZ3NfdGVjdCA8LSBzdW1tYXJ5X2xpc3RfdGVjdCRzdW1tYXJ5X3BjYSRyb3RhdGlvbgprbml0cjo6a2FibGUocm91bmQobG9hZGluZ3NfdGVjdFssMTozXSwzKSkgI1RhYmxlIG9mIGxvYWRpbmcgc2NvcmVzIGZvciB0aGUgZmlyc3QgMyBQQ3MuIApgYGAKCiMjIyBUZWN0YXJjaHVzIG92b2Jlc3N1cwoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9VFJVRX0Kc3VtbWFyeV9saXN0X3RlY3Rfb3ZvIDwtCiAgc3BlY2llc19wY2FfZnVuKGxvY19jbGltLAogICAgICAgICAgICAgICAgICBnZW51cyA9ICJ0ZWN0YXJjaHVzIiwKICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJvdm9iZXNzdXMiKQoKdGVjdF9vdm9fcGxvdCA8LQogIHBsb3RfY2xpbV9wY2Eoc3VtbWFyeV9saXN0X3RlY3Rfb3ZvJGxvY19jbGltLAogICAgICAgICAgICAgICAgc3VtbWFyeV9saXN0X3RlY3Rfb3ZvJHN1bW1hcnlfcGNhLAogICAgICAgICAgICAgICAgZmFjdG9yID0gInJlcHJvZHVjdGl2ZV9tb2RlIikKCnRlY3Rfb3ZvX3Bsb3QKCiMgc2F2ZSB0aGUgcGxvdApodG1sd2lkZ2V0czo6c2F2ZVdpZGdldCh0ZWN0X292b19wbG90LAogICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgInRlY3Rfb3ZvX3BjYS5odG1sIiksCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGZjb250YWluZWQgPSBUUlVFKQoKI2ZpbHRlciBsb2NhbGl0aWVzIGZvciB0aGUgZm9jYWwgc3BlY2llcwp0ZWN0X292b19sb2MgPC0gbG9jICU+JQogIGZpbHRlcihnZW51cyA9PSAidGVjdGFyY2h1cyIsIHNwZWNpZXMgPT0gIm92b2Jlc3N1cyIpCgojdXNlIHNvdXJjZWQgcGxvdF9sb2NzX2xlYWZsZXQgc2NyaXB0IHRvIHBsb3QgbG9jYWxpdGllcwp0ZWN0X292b19tYXAgPC0gcGxvdF9sb2NzX2xlYWZsZXQodGVjdF9vdm9fbG9jLCAicmVwcm9kdWN0aXZlX21vZGUiKQoKdGVjdF9vdm9fbWFwCiMgc2F2ZSB0aGUgbWFwCm1hcHZpZXc6Om1hcHNob3QoCiAgdGVjdF9vdm9fbWFwLAogIHVybCA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAidGVjdF9vdm9fbWFwLmh0bWwiKSwKICBmaWxlID0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJ0ZWN0X292b19tYXAucGRmIikKKQpgYGAKCgojIyMjIyBFTkZBCgpOb3cgSSdtIGdvaW5nIHRvIHBlcmZvcm0gZW52aXJvbm1lbnRhbCBuaWNoZSBmYWN0b3IgYW5hbHlzaXMgd2l0aCBzZXh1YWwgYW5kIGFzZXh1YWwgcG9wdWxhdGlvbnMgd2l0aGluIHRoZSBzcGVjaWVzLgpgYGB7ciBjYWNoZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIGdldCBiYWNrZ3JvdW5kIGVudid0IGZvciB0aGUgc3BlY2llcwp0ZWN0X292b19iZ19lbnYgPC0gYmdfZW52X2Nyb3AoCiAgdGVjdF9sb2MsCiAgc3BlY2llcyA9ICJvdm9iZXNzdXMiLAogIGVudmlyb25tZW50ID0gdywKICBidWZmZXIgPSAwLjUKKQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwp0ZWN0X292b19zZXh1YWxfZW5mYSA8LSBlbmZhX2NhbGNfZnVuKAogIGxvY3MgPSB0ZWN0X2xvYywKICBzcGVjaWVzID0gIm92b2Jlc3N1cyIsCiAgcmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIiwKICBtYXNrX3Jhc3RlciA9IHRlY3Rfb3ZvX2JnX2VudgopCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwp0ZWN0X292b19hc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bigKICBsb2NzID0gdGVjdF9sb2MsCiAgc3BlY2llcyA9ICJvdm9iZXNzdXMiLAogIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLAogIG1hc2tfcmFzdGVyID0gdGVjdF9vdm9fYmdfZW52CikKCiMgd3JpdGUgc2NvcmVzIHRvIGNzdnMKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X292b19hc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X292b19hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9vdm9fc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X292b19zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKI3Bsb3QgdGhlIG1hcmdpbmFsaXR5IHNjb3Jlcwp0ZWN0X292b19tYXJnaW5hbGl0eSA8LQogIG1hcmdpbmFsaXR5X2xvbGxpcG9wKAogICAgc2V4X21hcmcgPSB0ZWN0X292b19zZXh1YWxfZW5mYSRtLAogICAgYXNleF9tYXJnID0gdGVjdF9vdm9fYXNleHVhbF9lbmZhJG0sCiAgICBmdWxsX3NwZWNpZXNfbmFtZSA9ICJUZWN0YXJjaHVzIG92b2Jlc3N1cyIKICApCgp0ZWN0X292b19tYXJnaW5hbGl0eQoKZ2dzYXZlKAogICJ0ZWN0X292b19tYXJnaW5hbGl0eV9sb2xsaXBvcC5wbmciLAogIHBsb3QgPSB0ZWN0X292b19tYXJnaW5hbGl0eSwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKYGBgCgoKQSBjb3VwbGUgZGlmZmVyZW50IHdheXMgdG8gdmlzdWFsaXplIHRoZSBlbnZpcm9ubWVudGFsIHZhcmlhdGlvbi4gMSkgU2NhdHRlcnBsb3QgdmlzdWFsaXphdGlvbnMgb2YgbWFyZ2luYWxpdHkgdnMgYXhpcyAxIG9mIHRoZSBzcGVjaWFsaXphdGlvbiB3aXRoIHRoZSBsYWJlbHMgcmVtb3ZlZCAodGhleSBtYWtlIHRoaW5ncyBpbmRpc2Nlcm5hYmxlKS4gUmVkID0gb2NjdXBpZWQgZS1zcGFjZS4gR3JheSA9IEJhY2tncm91bmQgZS1zcGFjZS4gMikgRU5GQSBoaXN0b2dyYW0gdmlzdWFsaXphdGlvbnMgb2YgbWFyZ2luYWxpdHkgYW5kIHNwZWNpYWxpemF0aW9uIGF4ZXMuIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlIHdpdGggY29sb3JzIGNvcnJlc3BvbmRpbmcgdG8gc2V4dWFsIHZzLiBhc2V4dWFsIHBvcHVsYXRpb25zLiAKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKdGVjdF9vdm9fYXNleHVhbF9kZiA8LSB0ZWN0X292b19hc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSB0ZWN0X292b19hc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KHRlY3Rfb3ZvX2FzZXh1YWxfZGYsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX2FzZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgp0ZWN0X292b19zZXh1YWxfZGYgPC0gdGVjdF9vdm9fc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSB0ZWN0X292b19zZXh1YWxfZW5mYSRwcikKCnJlYWRyOjp3cml0ZV9jc3YodGVjdF9vdm9fc2V4dWFsX2RmLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X292b19zZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgojIGFzZXh1YWwKdGVjdF9vdm9fZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdCh0ZWN0X292b19hc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgidGVjdF9vdm9fZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X292b19lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKI3NleHVhbAp0ZWN0X292b19lbmZhX3NwZWNfc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QodGVjdF9vdm9fc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJTZXh1YWwiKQoKZ2dzYXZlKCJ0ZWN0X292b19lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fZW5mYV9zcGVjX3NleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiNhc2V4dWFsCmhpc3QodGVjdF9vdm9fYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdF9vdm9fYXNleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QodGVjdF9vdm9fYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKI3NleHVhbApoaXN0KHRlY3Rfb3ZvX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJ0ZWN0X292b19zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KHRlY3Rfb3ZvX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgojIyMgMykgUENBIG9mIHRvdGFsIGUtc3BhY2UKdGVjdF9vdm9fdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gdGVjdF9vdm9fYmdfZW52LCBsb2NzID0gdGVjdF9sb2MsIGdlbnVzID0gIlRlY3RhcmNodXMiLCBzcGVjaWVzID0gIm92b2Jlc3N1cyIpCgp0ZWN0X292b190b3RhbF9wY2EKCmdnc2F2ZSgidGVjdF9vdm9fdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fdG90YWxfcGNhLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpgYGAKClRyeWluZyBvdXQgYSByZXBlYXQgb2YgdGhlIGFuYWx5c2VzIHdpdGggcmVkdWNlZCBlbnZpcm9ubWVudGFsIHNwYWNlLgpQcmlvcml0aXppbmcgdmFyaWFibGVzIHRoYXQgd2lsbCBsaW1pdCB0aGVpciBkaXN0cmlidXRpb24gKGkuZS4gdmFyaWFibGVzIHRoYXQgcmVwcmVzZW50IHRoZSBleHRyZW1lcykuIEFmdGVyIGNvcnJlbGF0aW9uIGFuYWx5c2lzLCB3ZSdyZSBsZWZ0IHdpdGggQklPNCwgQklPOCwgQklPMTEsIEJJTzE1LCBCSU8xNwpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFBDQSBvZiBiYWNrZ3JvdW5kIGUtc3BhY2UuIFJlc3VsdGluZyBsaXN0IGlzIGEgY29ycmVsYXRpb24gaGVhdG1hcCAoY29yX2hlYXRtYXApLCBhIHRpYmJsZSBvZiB0aGUgcmFzdGVycyB3aXRoIGNvcnJlbGF0aW9uID4gdGhlIGN1dG9mZiAoZGVmYXVsdCBpcyAwLjc1KSwgYW5kIGEgdGliYmxlIG9mIGFsbCBwYWlyd2lzZSBjb3JyZWxhdGlvbnMKdGVjdF9vdm9fcGNhIDwtIHJhc3Rlcl9jb3JyZWxhdGlvbihyYXN0ZXJfc3RhY2sgPSB0ZWN0X292b19iZ19lbnYpCnRlY3Rfb3ZvX3BjYSRjb3JfaGVhdG1hcAp0ZWN0X292b19wY2EkdG9wX2NvciAlPiUga25pdHI6OmthYmxlKCkKCmdnc2F2ZSgidGVjdF9vdm9fcGNhX2NvcnIucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X292b19wY2EkY29yX2hlYXRtYXAsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgd3JpdGUgY29ycmVsYXRpb24gZGF0YSBmcmFtZSB0byBmaWxlCnJlYWRyOjp3cml0ZV9jc3YodGVjdF9vdm9fcGNhJHRvcF9jb3IsIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX3RvcF9jb3IuY3N2IikpCgpgYGAKCiMjIyMjIyBFTkZBIFJlZHVjZWQKClJlcGVhdCB0aGUgYW5hbHlzaXMgd2l0aCB0aGUgcmVkdWNlZCBkYXRhIHNldC4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kd190ZWN0X292byA8LSByYXN0ZXI6OnN1YnNldCh3LCBjKCJiaW80IiwgImJpbzgiLCAiYmlvMTEiLCAiYmlvMTUiLCAiYmlvMTciKSkKCiNnZXQgYmFja2dyb3VuZCBlbnYndCBmb3IgdGhlIHNwZWNpZXMKdGVjdF9vdm9fYmdfZW52X3N1YnNldCA8LSBiZ19lbnZfY3JvcCh0ZWN0X2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAib3ZvYmVzc3VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQgPSB3X3RlY3Rfb3ZvLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gMC41KQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwp0ZWN0X292b19zZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gdGVjdF9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJvdm9iZXNzdXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSB0ZWN0X292b19iZ19lbnZfc3Vic2V0KQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKdGVjdF9vdm9fYXNleHVhbF9lbmZhX3N1YnNldCA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSB0ZWN0X2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJvdm9iZXNzdXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSB0ZWN0X292b19iZ19lbnZfc3Vic2V0KQoKIyB3cml0ZSBtYXJnaW5hbGl0eSBzY29yZXMgdG8gY3N2CnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9vdm9fYXNleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX3N1YnNldF9hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9vdm9fc2V4dWFsX2VuZmFfc3Vic2V0JG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9vdm9fc3Vic2V0X3NleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgojIHBsb3QgdGhlIG1hcmdpbmFsaXR5IHNjb3Jlcwp0ZWN0X292b19zdWJzZXRfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gdGVjdF9vdm9fc2V4dWFsX2VuZmFfc3Vic2V0JG0sCiAgICBhc2V4X21hcmcgPSB0ZWN0X292b19hc2V4dWFsX2VuZmFfc3Vic2V0JG0sCiAgICBmdWxsX3NwZWNpZXNfbmFtZSA9ICJUZWN0YXJjaHVzIG92b2Jlc3N1cyIKICApCgp0ZWN0X292b19zdWJzZXRfbWFyZ2luYWxpdHkKCmdnc2F2ZSgidGVjdF9vdm9fc3Vic2V0X21hcmdpbmFsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fc3Vic2V0X21hcmdpbmFsaXR5LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpgYGAKClZpc3VhbGl6ZSB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojIGFjY2VzcyB0aGUgcmVsZXZhbnQgdmFsdWVzIGZvciBwbG90dGluZwp0ZWN0X292b19hc2V4dWFsX2RmX3N1YnNldCA8LSB0ZWN0X292b19hc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gdGVjdF9vdm9fYXNleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9vdm9fYXNleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9vdm9fYXNleHVhbF9kZl9zdWJzZXQuY3N2IikKKQoKCnRlY3Rfb3ZvX3NleHVhbF9kZl9zdWJzZXQgPC0gdGVjdF9vdm9fc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gdGVjdF9vdm9fc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X292b19zZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX3NleHVhbF9kZl9zdWJzZXQuY3N2IikKKQoKIyBhc2V4dWFsCnRlY3Rfb3ZvX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbCA8LSBlbmZhX2hleF9wbG90KHRlY3Rfb3ZvX2FzZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgidGVjdF9vdm9fc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNleHVhbAp0ZWN0X292b19zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KHRlY3Rfb3ZvX3NleHVhbF9kZl9zdWJzZXQsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoInRlY3Rfb3ZvX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojIGFzZXh1YWwKaGlzdCh0ZWN0X292b19hc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdF9vdm9fc3Vic2V0X2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KHRlY3Rfb3ZvX2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgoKIyBzZXh1YWwKaGlzdCh0ZWN0X292b19zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgInRlY3Rfb3ZvX3N1YnNldF9zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KHRlY3Rfb3ZvX3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCnRlY3Rfb3ZvX3N1YnNldF90b3RhbF9wY2EgPC0gdG90YWxfY2xpbWF0ZV9wY2FfcGxvdChiZ19lbnYgPSB0ZWN0X292b19iZ19lbnZfc3Vic2V0LCBsb2NzID0gdGVjdF9sb2MsIGdlbnVzID0gIlRlY3RhcmNodXMiLCBzcGVjaWVzID0gIm92b2Jlc3N1cyIpCgp0ZWN0X292b19zdWJzZXRfdG90YWxfcGNhCgpnZ3NhdmUoInRlY3Rfb3ZvX3N1YnNldF90b3RhbF9wY2EucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X292b19zdWJzZXRfdG90YWxfcGNhLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNhdmUgZW5mYSBvYmplY3RzIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSBlbnZpcm9ubWVudC4gVGhleSB0YWtlIHVwIGEgbG90IG9mIG1lbW9yeS4Kc2F2ZVJEUyh0ZWN0X292b19zZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3Rfb3ZvX3NleHVhbF9lbmZhLlJEUyIpKQpybSh0ZWN0X292b19zZXh1YWxfZW5mYSkKCnNhdmVSRFModGVjdF9vdm9fYXNleHVhbF9lbmZhLCBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAidGVjdF9vdm9fYXNleHVhbF9lbmZhLlJEUyIpKQpybSh0ZWN0X292b19hc2V4dWFsX2VuZmEpCgpzYXZlUkRTKHRlY3Rfb3ZvX3NleHVhbF9lbmZhX3N1YnNldCwKICAgICAgICBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAidGVjdF9vdm9fc3Vic2V0X3NleHVhbF9lbmZhLlJEUyIpKQpybSh0ZWN0X292b19zZXh1YWxfZW5mYV9zdWJzZXQpCgpzYXZlUkRTKHRlY3Rfb3ZvX2FzZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3Rfb3ZvX3N1YnNldF9hc2V4dWFsX2VuZmEuUkRTIikpCnJtKHRlY3Rfb3ZvX2FzZXh1YWxfZW5mYV9zdWJzZXQpCmBgYAoKIyMjIyMgU3RhYmlsaXR5CgpXZSdyZSBhbHNvIGludGVyZXN0ZWQgaW4gc2VlaW5nIGlmIGFzZXh1YWwgcG9wdWxhdGlvbnMgbGl2ZSBpbiBtb3JlIHVuc3RhYmxlIGNsaW1hdGljIGFyZWFzIHJlbGF0aXZlIHRvIHNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnRlY3Rfb3ZvX2xvY3NfYXNleHVhbCA8LSB0ZWN0X292b19sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gImFzZXh1YWwiLAogICAgICAgICBzcGVjaWVzID09ICJvdm9iZXNzdXMiLAogICAgICAgICAhZHVwbGljYXRlZChsYXRfbG9uZykpICU+JSAKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgp0ZWN0X292b19sb2NzX3NleHVhbCA8LSB0ZWN0X292b19sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gInNleHVhbCIsCiAgICAgICAgIHNwZWNpZXMgPT0gIm92b2Jlc3N1cyIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCnByZWNpcF9hc2V4dWFsX3RlY3Rfb3ZvIDwtIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgdGVjdF9vdm9fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKcHJlY2lwX3NleHVhbF90ZWN0X292byA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3Rfb3ZvX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpwcmVjaXBfZGZfdGVjdF9vdm8gPC0gYmluZF9yb3dzKHByZWNpcF9hc2V4dWFsX3RlY3Rfb3ZvLCBwcmVjaXBfc2V4dWFsX3RlY3Rfb3ZvKQoKcmVhZHI6OndyaXRlX2NzdihwcmVjaXBfZGZfdGVjdF9vdm8sIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX3ByZWNpcF9zdGFiaWxpdHlfZGYuY3N2IikpCgp0ZWN0X292b19wcmVjaXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwcmVjaXBfZGZfdGVjdF9vdm8sIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKdGVjdF9vdm9fcHJlY2lwX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoInRlY3Rfb3ZvX3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X292b19wcmVjaXBfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCnRlbXBfYXNleHVhbF90ZWN0X292byA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCB0ZWN0X292b19sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKdGVtcF9zZXh1YWxfdGVjdF9vdm8gPC0gcmFzdGVyOjpleHRyYWN0KHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgdGVjdF9vdm9fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmX3RlY3Rfb3ZvIDwtIGJpbmRfcm93cyh0ZW1wX2FzZXh1YWxfdGVjdF9vdm8sIHRlbXBfc2V4dWFsX3RlY3Rfb3ZvKQoKcmVhZHI6OndyaXRlX2Nzdih0ZW1wX2RmX3RlY3Rfb3ZvLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X292b190ZW1wX3N0YWJpbGl0eV9kZi5jc3YiKSkKCnRlY3Rfb3ZvX3RlbXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSB0ZW1wX2RmX3RlY3Rfb3ZvLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gdGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgp0ZWN0X292b190ZW1wX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoInRlY3Rfb3ZvX3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X292b190ZW1wX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpvdmVyYWxsX2FzZXh1YWxfdGVjdF9vdm8gPC0gcmFzdGVyOjpleHRyYWN0KG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgdGVjdF9vdm9fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCm92ZXJhbGxfc2V4dWFsX3RlY3Rfb3ZvIDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3Rfb3ZvX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKb3ZlcmFsbF9kZl90ZWN0X292byA8LSBiaW5kX3Jvd3Mob3ZlcmFsbF9hc2V4dWFsX3RlY3Rfb3ZvLCBvdmVyYWxsX3NleHVhbF90ZWN0X292bykKCnJlYWRyOjp3cml0ZV9jc3Yob3ZlcmFsbF9kZl90ZWN0X292bywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9vdm9fb3ZlcmFsbF9zdGFiaWxpdHlfZGYuY3N2IikpCgp0ZWN0X292b19vdmVyYWxsX3N0YWJpbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gb3ZlcmFsbF9kZl90ZWN0X292bywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKdGVjdF9vdm9fb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJ0ZWN0X292b19vdmVyYWxsX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IHRlY3Rfb3ZvX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKYGBgCgojIyMjIyBTZWFzb25hbGl0eQpgYGB7cn0Kc2Vhc19wcmVjaXBfYXNleHVhbF90ZWN0X292byA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW8xNSwgdGVjdF9vdm9fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnNlYXNfcHJlY2lwX3NleHVhbF90ZWN0X292byA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW8xNSwgdGVjdF9vdm9fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc2Vhc29uYWxpdHkiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpzZWFzX3ByZWNpcF9kZl90ZWN0X292byA8LSBiaW5kX3Jvd3Moc2Vhc19wcmVjaXBfYXNleHVhbF90ZWN0X292bywgc2Vhc19wcmVjaXBfc2V4dWFsX3RlY3Rfb3ZvKQoKcmVhZHI6OndyaXRlX2NzdihzZWFzX3ByZWNpcF9kZl90ZWN0X292bywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9vdm9fcHJlY2lwX3NlYXNvbmFsaXR5X2RmLmNzdiIpKQoKdGVjdF9vdm9fcHJlY2lwX3NlYXNvbmFsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBzZWFzX3ByZWNpcF9kZl90ZWN0X292bywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zZWFzb25hbGl0eSwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKdGVjdF9vdm9fcHJlY2lwX3NlYXNvbmFsaXR5X3Bsb3QKCmdnc2F2ZSgKICAidGVjdF9vdm9fcHJlY2lwX3NlYXNvbmFsaXR5LnBuZyIsCiAgcGxvdCA9IHRlY3Rfb3ZvX3ByZWNpcF9zZWFzb25hbGl0eV9wbG90LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQoKc2Vhc190ZW1wX2FzZXh1YWxfdGVjdF9vdm8gPC0gcmFzdGVyOjpleHRyYWN0KHckYmlvNCwgdGVjdF9vdm9fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zZWFzb25hbGl0eSIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpzZWFzX3RlbXBfc2V4dWFsX3RlY3Rfb3ZvIDwtIHJhc3Rlcjo6ZXh0cmFjdCh3JGJpbzQsIHRlY3Rfb3ZvX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zZWFzb25hbGl0eSIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnNlYXNfdGVtcF9kZl90ZWN0X292byA8LSBiaW5kX3Jvd3Moc2Vhc190ZW1wX2FzZXh1YWxfdGVjdF9vdm8sIHNlYXNfdGVtcF9zZXh1YWxfdGVjdF9vdm8pCgpyZWFkcjo6d3JpdGVfY3N2KHNlYXNfdGVtcF9kZl90ZWN0X292bywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9vdm9fdGVtcF9zZWFzb25hbGl0eV9kZi5jc3YiKSkKCnRlY3Rfb3ZvX3RlbXBfc2Vhc29uYWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHNlYXNfdGVtcF9kZl90ZWN0X292bywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHRlbXBfc2Vhc29uYWxpdHksIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCnRlY3Rfb3ZvX3RlbXBfc2Vhc29uYWxpdHlfcGxvdAoKZ2dzYXZlKAogICJ0ZWN0X292b190ZW1wX3NlYXNvbmFsaXR5LnBuZyIsCiAgcGxvdCA9IHRlY3Rfb3ZvX3RlbXBfc2Vhc29uYWxpdHlfcGxvdCwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKYGBgCiMjIyMjIE1vdmUgb3V0cHV0CgpQdXQgYWxsIG91dHB1dCBpbnRvIHNwZWNpZXMtc3BlY2lmaWMgc3ViZm9sZGVycy4KYGBge3IgcmVzdWx0cz0iaGlkZSJ9CnRlY3Rfb3ZvX291dF9pbnRfcGF0aCA8LSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgInRlY3RhcmNodXNfb3ZvYmVzc3VzIikKdGVjdF9vdm9fb3V0X3Bsb3RfcGF0aCA8LSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdGFyY2h1c19vdm9iZXNzdXMiKQp0ZWN0X292b19vdXRfc3ByZWFkX3BhdGggPC0gZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdGFyY2h1c19vdm9iZXNzdXMiKQp0ZWN0X292b19vdXRfb2JqX3BhdGggPC0gZmlsZS5wYXRoKG9ial9wYXRoLCAidGVjdGFyY2h1c19vdm9iZXNzdXMiKQoKIyBtb3ZlIGludGVyYWN0aXZlCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gaW50ZXJhY3RpdmVfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gdGVjdF9vdm9fb3V0X2ludF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJ0ZWN0X292byIpCiMgbW92ZSBwbG90cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gdGVjdF9vdm9fb3V0X3Bsb3RfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAidGVjdF9vdm8iKQoKIyBtb3ZlIHNwcmVhZHNoZWV0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHNwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSB0ZWN0X292b19vdXRfc3ByZWFkX3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gInRlY3Rfb3ZvIikKCiMgbW92ZSBvYmplY3RzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gb2JqX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IHRlY3Rfb3ZvX291dF9vYmpfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAidGVjdF9vdm8iKQpgYGAKCgojIyMgVGVjdGFyY2h1cyBodXR0b25pCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1UUlVFfQpzdW1tYXJ5X2xpc3RfdGVjdF9odXR0IDwtCiAgc3BlY2llc19wY2FfZnVuKGxvY19jbGltLAogICAgICAgICAgICAgICAgICBnZW51cyA9ICJ0ZWN0YXJjaHVzIiwKICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJodXR0b25pIikKCnRlY3RfaHV0dF9wbG90IDwtCiAgcGxvdF9jbGltX3BjYShzdW1tYXJ5X2xpc3RfdGVjdF9odXR0JGxvY19jbGltLAogICAgICAgICAgICAgICAgc3VtbWFyeV9saXN0X3RlY3RfaHV0dCRzdW1tYXJ5X3BjYSwKICAgICAgICAgICAgICAgIGZhY3RvciA9ICJyZXByb2R1Y3RpdmVfbW9kZSIpCgp0ZWN0X2h1dHRfcGxvdAoKIyBzYXZlIHRoZSBwbG90Cmh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KHRlY3RfaHV0dF9wbG90LAogICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgInRlY3RfaHV0dF9wY2EuaHRtbCIpLAogICAgICAgICAgICAgICAgICAgICAgICBzZWxmY29udGFpbmVkID0gVFJVRSkKCiNmaWx0ZXIgbG9jYWxpdGllcyBmb3IgdGhlIGZvY2FsIHNwZWNpZXMKdGVjdF9odXR0X2xvYyA8LSBsb2MgJT4lCiAgZmlsdGVyKGdlbnVzID09ICJ0ZWN0YXJjaHVzIiwgc3BlY2llcyA9PSAiaHV0dG9uaSIpCgojdXNlIHNvdXJjZWQgcGxvdF9sb2NzX2xlYWZsZXQgc2NyaXB0IHRvIHBsb3QgbG9jYWxpdGllcwp0ZWN0X2h1dHRfbWFwIDwtIHBsb3RfbG9jc19sZWFmbGV0KHRlY3RfaHV0dF9sb2MsICJyZXByb2R1Y3RpdmVfbW9kZSIpCgp0ZWN0X2h1dHRfbWFwCiMgc2F2ZSB0aGUgbWFwCm1hcHZpZXc6Om1hcHNob3QoCiAgdGVjdF9odXR0X21hcCwKICB1cmwgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgInRlY3RfaHV0dF9tYXAuaHRtbCIpLAogIGZpbGUgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgInRlY3RfaHV0dF9tYXAucGRmIikKKQpgYGAKCiMjIyMjIEVORkEKTm93IEknbSBnb2luZyB0byBwZXJmb3JtIGVudmlyb25tZW50YWwgbmljaGUgZmFjdG9yIGFuYWx5c2lzIHdpdGggc2V4dWFsIGFuZCBhc2V4dWFsIHBvcHVsYXRpb25zIHdpdGhpbiB0aGUgc3BlY2llcy4KYGBge3IgY2FjaGU9VFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBnZXQgYmFja2dyb3VuZCBlbnYndCBmb3IgdGhlIHNwZWNpZXMKdGVjdF9odXR0X2JnX2VudiA8LSBiZ19lbnZfY3JvcCgKICB0ZWN0X2xvYywKICBzcGVjaWVzID0gImh1dHRvbmkiLAogIGVudmlyb25tZW50ID0gdywKICBidWZmZXIgPSAwLjUKKQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwp0ZWN0X2h1dHRfc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bigKICBsb2NzID0gdGVjdF9sb2MsCiAgc3BlY2llcyA9ICJodXR0b25pIiwKICByZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiLAogIG1hc2tfcmFzdGVyID0gdGVjdF9odXR0X2JnX2VudgopCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwp0ZWN0X2h1dHRfYXNleHVhbF9lbmZhIDwtIGVuZmFfY2FsY19mdW4oCiAgbG9jcyA9IHRlY3RfbG9jLAogIHNwZWNpZXMgPSAiaHV0dG9uaSIsCiAgcmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIsCiAgbWFza19yYXN0ZXIgPSB0ZWN0X2h1dHRfYmdfZW52CikKCiMgd3JpdGUgc2NvcmVzIHRvIGNzdnMKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X2h1dHRfYXNleHVhbF9lbmZhJG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X2h1dHRfc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X2h1dHRfc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCiNwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKdGVjdF9odXR0X21hcmdpbmFsaXR5IDwtCiAgbWFyZ2luYWxpdHlfbG9sbGlwb3AoCiAgICBzZXhfbWFyZyA9IHRlY3RfaHV0dF9zZXh1YWxfZW5mYSRtLAogICAgYXNleF9tYXJnID0gdGVjdF9odXR0X2FzZXh1YWxfZW5mYSRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiVGVjdGFyY2h1cyBodXR0b25pIgogICkKCnRlY3RfaHV0dF9tYXJnaW5hbGl0eQoKZ2dzYXZlKAogICJ0ZWN0X2h1dHRfbWFyZ2luYWxpdHlfbG9sbGlwb3AucG5nIiwKICBwbG90ID0gdGVjdF9odXR0X21hcmdpbmFsaXR5LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQpgYGAKCkEgY291cGxlIGRpZmZlcmVudCB3YXlzIHRvIHZpc3VhbGl6ZSB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24uIDEpIFNjYXR0ZXJwbG90IHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IHZzIGF4aXMgMSBvZiB0aGUgc3BlY2lhbGl6YXRpb24gd2l0aCB0aGUgbGFiZWxzIHJlbW92ZWQgKHRoZXkgbWFrZSB0aGluZ3MgaW5kaXNjZXJuYWJsZSkuIFJlZCA9IG9jY3VwaWVkIGUtc3BhY2UuIEdyYXkgPSBCYWNrZ3JvdW5kIGUtc3BhY2UuIDIpIEVORkEgaGlzdG9ncmFtIHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IGFuZCBzcGVjaWFsaXphdGlvbiBheGVzLiAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZSB3aXRoIGNvbG9ycyBjb3JyZXNwb25kaW5nIHRvIHNleHVhbCB2cy4gYXNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojYWNjZXNzIHRoZSByZWxldmFudCB2YWx1ZXMgZm9yIHBsb3R0aW5nCnRlY3RfaHV0dF9hc2V4dWFsX2RmIDwtIHRlY3RfaHV0dF9hc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSB0ZWN0X2h1dHRfYXNleHVhbF9lbmZhJHByKQoKcmVhZHI6OndyaXRlX2Nzdih0ZWN0X2h1dHRfYXNleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X2FzZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgp0ZWN0X2h1dHRfc2V4dWFsX2RmIDwtIHRlY3RfaHV0dF9zZXh1YWxfZW5mYSRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IHRlY3RfaHV0dF9zZXh1YWxfZW5mYSRwcikKCnJlYWRyOjp3cml0ZV9jc3YodGVjdF9odXR0X3NleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3NleHVhbF9tYXJnaW5hbGl0eV9kZi5jc3YiKSkKCiMgYXNleHVhbAp0ZWN0X2h1dHRfZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdCh0ZWN0X2h1dHRfYXNleHVhbF9kZiwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiQXNleHVhbCIpCgpnZ3NhdmUoInRlY3RfaHV0dF9lbmZhX3NwZWNfYXNleHVhbC5wbmciLAogICAgICAgcGxvdCA9IHRlY3RfaHV0dF9lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKI3NleHVhbAp0ZWN0X2h1dHRfZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KHRlY3RfaHV0dF9zZXh1YWxfZGYsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoInRlY3RfaHV0dF9lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9odXR0X2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojYXNleHVhbApoaXN0KHRlY3RfaHV0dF9hc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJ0ZWN0X2h1dHRfYXNleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QodGVjdF9odXR0X2FzZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiNzZXh1YWwKaGlzdCh0ZWN0X2h1dHRfc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgInRlY3RfaHV0dF9zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KHRlY3RfaHV0dF9zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCnRlY3RfaHV0dF90b3RhbF9wY2EgPC0gdG90YWxfY2xpbWF0ZV9wY2FfcGxvdChiZ19lbnYgPSB0ZWN0X2h1dHRfYmdfZW52LCBsb2NzID0gdGVjdF9sb2MsIGdlbnVzID0gIlRlY3RhcmNodXMiLCBzcGVjaWVzID0gImh1dHRvbmkiKQoKdGVjdF9odXR0X3RvdGFsX3BjYQoKZ2dzYXZlKCJ0ZWN0X2h1dHRfdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9odXR0X3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgojIyMjIyMgRU5GQSBSZWR1Y2VkClRyeWluZyBvdXQgYSByZXBlYXQgb2YgdGhlIGFuYWx5c2VzIHdpdGggcmVkdWNlZCBlbnZpcm9ubWVudGFsIHNwYWNlLgpQcmlvcml0aXppbmcgdmFyaWFibGVzIHRoYXQgd2lsbCBsaW1pdCB0aGVpciBkaXN0cmlidXRpb24gKGkuZS4gdmFyaWFibGVzIHRoYXQgcmVwcmVzZW50IHRoZSBleHRyZW1lcykuIEFmdGVyIGNvcnJlbGF0aW9uIGFuYWx5c2lzLCB3ZSdyZSBsZWZ0IHdpdGggQklPNCwgQklPOCwgQklPMTEsIEJJTzE1LCBCSU8xNwpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFBDQSBvZiBiYWNrZ3JvdW5kIGUtc3BhY2UuIFJlc3VsdGluZyBsaXN0IGlzIGEgY29ycmVsYXRpb24gaGVhdG1hcCAoY29yX2hlYXRtYXApLCBhIHRpYmJsZSBvZiB0aGUgcmFzdGVycyB3aXRoIGNvcnJlbGF0aW9uID4gdGhlIGN1dG9mZiAoZGVmYXVsdCBpcyAwLjc1KSwgYW5kIGEgdGliYmxlIG9mIGFsbCBwYWlyd2lzZSBjb3JyZWxhdGlvbnMKdGVjdF9odXR0X3BjYSA8LSByYXN0ZXJfY29ycmVsYXRpb24ocmFzdGVyX3N0YWNrID0gdGVjdF9odXR0X2JnX2VudikKdGVjdF9odXR0X3BjYSRjb3JfaGVhdG1hcAp0ZWN0X2h1dHRfcGNhJHRvcF9jb3IgJT4lIGtuaXRyOjprYWJsZSgpCgpnZ3NhdmUoInRlY3RfaHV0dF9wY2FfY29yci5wbmciLAogICAgICAgcGxvdCA9IHRlY3RfaHV0dF9wY2EkY29yX2hlYXRtYXAsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgd3JpdGUgY29ycmVsYXRpb24gZGF0YSBmcmFtZSB0byBmaWxlCnJlYWRyOjp3cml0ZV9jc3YodGVjdF9odXR0X3BjYSR0b3BfY29yLCBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X2h1dHRfdG9wX2Nvci5jc3YiKSkKCmBgYAoKUmVwZWF0IHRoZSBhbmFseXNpcyB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp3X3RlY3RfaHV0dCA8LSByYXN0ZXI6OnN1YnNldCh3LCBjKCJiaW80IiwgImJpbzgiLCAiYmlvMTEiLCAiYmlvMTUiLCAiYmlvMTciKSkKCiNnZXQgYmFja2dyb3VuZCBlbnYndCBmb3IgdGhlIHNwZWNpZXMKdGVjdF9odXR0X2JnX2Vudl9zdWJzZXQgPC0gYmdfZW52X2Nyb3AodGVjdF9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImh1dHRvbmkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCA9IHdfdGVjdF9odXR0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gMC41KQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwp0ZWN0X2h1dHRfc2V4dWFsX2VuZmFfc3Vic2V0IDwtIGVuZmFfY2FsY19mdW4obG9jcyA9IHRlY3RfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiaHV0dG9uaSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IHRlY3RfaHV0dF9iZ19lbnZfc3Vic2V0KQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKdGVjdF9odXR0X2FzZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gdGVjdF9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiaHV0dG9uaSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IHRlY3RfaHV0dF9iZ19lbnZfc3Vic2V0KQoKIyB3cml0ZSBtYXJnaW5hbGl0eSBzY29yZXMgdG8gY3N2CnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9odXR0X2FzZXh1YWxfZW5mYV9zdWJzZXQkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X2h1dHRfc3Vic2V0X2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X2h1dHRfc2V4dWFsX2VuZmFfc3Vic2V0JG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3N1YnNldF9zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKIyBwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKdGVjdF9odXR0X3N1YnNldF9tYXJnaW5hbGl0eSA8LQogIG1hcmdpbmFsaXR5X2xvbGxpcG9wKAogICAgc2V4X21hcmcgPSB0ZWN0X2h1dHRfc2V4dWFsX2VuZmFfc3Vic2V0JG0sCiAgICBhc2V4X21hcmcgPSB0ZWN0X2h1dHRfYXNleHVhbF9lbmZhX3N1YnNldCRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiVGVjdGFyY2h1cyBodXR0b25pIgogICkKCnRlY3RfaHV0dF9zdWJzZXRfbWFyZ2luYWxpdHkKCmdnc2F2ZSgidGVjdF9odXR0X3N1YnNldF9tYXJnaW5hbGl0eS5wbmciLAogICAgICAgcGxvdCA9IHRlY3RfaHV0dF9zdWJzZXRfbWFyZ2luYWxpdHksCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmBgYAoKVmlzdWFsaXplIHdpdGggdGhlIHJlZHVjZWQgZGF0YSBzZXQuCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiMgYWNjZXNzIHRoZSByZWxldmFudCB2YWx1ZXMgZm9yIHBsb3R0aW5nCnRlY3RfaHV0dF9hc2V4dWFsX2RmX3N1YnNldCA8LSB0ZWN0X2h1dHRfYXNleHVhbF9lbmZhX3N1YnNldCRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IHRlY3RfaHV0dF9hc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X2h1dHRfYXNleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X2FzZXh1YWxfZGZfc3Vic2V0LmNzdiIpCikKCgp0ZWN0X2h1dHRfc2V4dWFsX2RmX3N1YnNldCA8LSB0ZWN0X2h1dHRfc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gdGVjdF9odXR0X3NleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9odXR0X3NleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3NleHVhbF9kZl9zdWJzZXQuY3N2IikKKQoKIyBhc2V4dWFsCnRlY3RfaHV0dF9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdCh0ZWN0X2h1dHRfYXNleHVhbF9kZl9zdWJzZXQsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIkFzZXh1YWwiKQoKZ2dzYXZlKCJ0ZWN0X2h1dHRfc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9odXR0X3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyBzZXh1YWwKdGVjdF9odXR0X3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QodGVjdF9odXR0X3NleHVhbF9kZl9zdWJzZXQsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoInRlY3RfaHV0dF9zdWJzZXRfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogICAgICAgcGxvdCA9IHRlY3RfaHV0dF9zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiMgYXNleHVhbApoaXN0KHRlY3RfaHV0dF9hc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdF9odXR0X3N1YnNldF9hc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdCh0ZWN0X2h1dHRfYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCgojIHNleHVhbApoaXN0KHRlY3RfaHV0dF9zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgInRlY3RfaHV0dF9zdWJzZXRfc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdCh0ZWN0X2h1dHRfc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgojIyMgMykgUENBIG9mIHRvdGFsIGUtc3BhY2UKdGVjdF9odXR0X3N1YnNldF90b3RhbF9wY2EgPC0gdG90YWxfY2xpbWF0ZV9wY2FfcGxvdChiZ19lbnYgPSB0ZWN0X2h1dHRfYmdfZW52X3N1YnNldCwgbG9jcyA9IHRlY3RfbG9jLCBnZW51cyA9ICJUZWN0YXJjaHVzIiwgc3BlY2llcyA9ICJodXR0b25pIikKCnRlY3RfaHV0dF9zdWJzZXRfdG90YWxfcGNhCgpnZ3NhdmUoInRlY3RfaHV0dF9zdWJzZXRfdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9odXR0X3N1YnNldF90b3RhbF9wY2EsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgc2F2ZSBlbmZhIG9iamVjdHMgYW5kIHJlbW92ZSB0aGVtIGZyb20gdGhlIGVudmlyb25tZW50LiBUaGV5IHRha2UgdXAgYSBsb3Qgb2YgbWVtb3J5LgpzYXZlUkRTKHRlY3RfaHV0dF9zZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3RfaHV0dF9zZXh1YWxfZW5mYS5SRFMiKSkKcm0odGVjdF9odXR0X3NleHVhbF9lbmZhKQoKc2F2ZVJEUyh0ZWN0X2h1dHRfYXNleHVhbF9lbmZhLCBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAidGVjdF9odXR0X2FzZXh1YWxfZW5mYS5SRFMiKSkKcm0odGVjdF9odXR0X2FzZXh1YWxfZW5mYSkKCnNhdmVSRFModGVjdF9odXR0X3NleHVhbF9lbmZhX3N1YnNldCwKICAgICAgICBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAidGVjdF9odXR0X3N1YnNldF9zZXh1YWxfZW5mYS5SRFMiKSkKcm0odGVjdF9odXR0X3NleHVhbF9lbmZhX3N1YnNldCkKCnNhdmVSRFModGVjdF9odXR0X2FzZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3RfaHV0dF9zdWJzZXRfYXNleHVhbF9lbmZhLlJEUyIpKQpybSh0ZWN0X2h1dHRfYXNleHVhbF9lbmZhX3N1YnNldCkKYGBgCgoKIyMjIyBTdGFiaWxpdHl5CldlJ3JlIGFsc28gaW50ZXJlc3RlZCBpbiBzZWVpbmcgaWYgYXNleHVhbCBwb3B1bGF0aW9ucyBsaXZlIGluIG1vcmUgdW5zdGFibGUgY2xpbWF0aWMgYXJlYXMgcmVsYXRpdmUgdG8gc2V4dWFsIHBvcHVsYXRpb25zLiAKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KdGVjdF9odXR0X2xvY3NfYXNleHVhbCA8LSB0ZWN0X2h1dHRfbG9jICU+JSAKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlLCBzZXAgPSAiXyIpKSAlPiUgCiAgZmlsdGVyKHJlcHJvZHVjdGl2ZV9tb2RlID09ICJhc2V4dWFsIiwKICAgICAgICAgc3BlY2llcyA9PSAiaHV0dG9uaSIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCnRlY3RfaHV0dF9sb2NzX3NleHVhbCA8LSB0ZWN0X2h1dHRfbG9jICU+JSAKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlLCBzZXAgPSAiXyIpKSAlPiUgCiAgZmlsdGVyKHJlcHJvZHVjdGl2ZV9tb2RlID09ICJzZXh1YWwiLAogICAgICAgICBzcGVjaWVzID09ICJodXR0b25pIiwKICAgICAgICAgIWR1cGxpY2F0ZWQobGF0X2xvbmcpKSAlPiUgCiAgZHBseXI6OnNlbGVjdChsb25naXR1ZGUsIGxhdGl0dWRlKQoKcHJlY2lwX2FzZXh1YWxfdGVjdF9odXR0IDwtIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgdGVjdF9odXR0X2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnByZWNpcF9zZXh1YWxfdGVjdF9odXR0IDwtIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgdGVjdF9odXR0X2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpwcmVjaXBfZGZfdGVjdF9odXR0IDwtIGJpbmRfcm93cyhwcmVjaXBfYXNleHVhbF90ZWN0X2h1dHQsIHByZWNpcF9zZXh1YWxfdGVjdF9odXR0KQoKcmVhZHI6OndyaXRlX2NzdihwcmVjaXBfZGZfdGVjdF9odXR0LCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X2h1dHRfcHJlY2lwX3N0YWJpbGl0eV9kZi5jc3YiKSkKCnRlY3RfaHV0dF9wcmVjaXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwcmVjaXBfZGZfdGVjdF9odXR0LCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gcHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCnRlY3RfaHV0dF9wcmVjaXBfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgidGVjdF9odXR0X3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X2h1dHRfcHJlY2lwX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgp0ZW1wX2FzZXh1YWxfdGVjdF9odXR0IDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3RfaHV0dF9sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKdGVtcF9zZXh1YWxfdGVjdF9odXR0IDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3RfaHV0dF9sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnRlbXBfZGZfdGVjdF9odXR0IDwtIGJpbmRfcm93cyh0ZW1wX2FzZXh1YWxfdGVjdF9odXR0LCB0ZW1wX3NleHVhbF90ZWN0X2h1dHQpCgpyZWFkcjo6d3JpdGVfY3N2KHRlbXBfZGZfdGVjdF9odXR0LCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X2h1dHRfdGVtcF9zdGFiaWxpdHlfZGYuY3N2IikpCgp0ZWN0X2h1dHRfdGVtcF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHRlbXBfZGZfdGVjdF9odXR0LCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gdGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgp0ZWN0X2h1dHRfdGVtcF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJ0ZWN0X2h1dHRfcHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IHRlY3RfaHV0dF90ZW1wX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpvdmVyYWxsX2FzZXh1YWxfdGVjdF9odXR0IDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3RfaHV0dF9sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKb3ZlcmFsbF9zZXh1YWxfdGVjdF9odXR0IDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3RfaHV0dF9sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCm92ZXJhbGxfZGZfdGVjdF9odXR0IDwtIGJpbmRfcm93cyhvdmVyYWxsX2FzZXh1YWxfdGVjdF9odXR0LCBvdmVyYWxsX3NleHVhbF90ZWN0X2h1dHQpCgpyZWFkcjo6d3JpdGVfY3N2KG92ZXJhbGxfZGZfdGVjdF9odXR0LCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X2h1dHRfb3ZlcmFsbF9zdGFiaWxpdHlfZGYuY3N2IikpCgp0ZWN0X2h1dHRfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IG92ZXJhbGxfZGZfdGVjdF9odXR0LCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gb3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgp0ZWN0X2h1dHRfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJ0ZWN0X2h1dHRfb3ZlcmFsbF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X2h1dHRfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQpgYGAKCiMjIyMjIFNlYXNvbmFsaXR5CmBgYHtyfQpzZWFzX3ByZWNpcF9hc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW8xNSwgdGVjdF9odXR0X2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zZWFzb25hbGl0eSIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpzZWFzX3ByZWNpcF9zZXh1YWxfdGVjdF9odXR0IDwtIHJhc3Rlcjo6ZXh0cmFjdCh3JGJpbzE1LCB0ZWN0X2h1dHRfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc2Vhc29uYWxpdHkiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpzZWFzX3ByZWNpcF9kZl90ZWN0X2h1dHQgPC0gYmluZF9yb3dzKHNlYXNfcHJlY2lwX2FzZXh1YWxfdGVjdF9odXR0LCBzZWFzX3ByZWNpcF9zZXh1YWxfdGVjdF9odXR0KQoKcmVhZHI6OndyaXRlX2NzdihzZWFzX3ByZWNpcF9kZl90ZWN0X2h1dHQsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3RfaHV0dF9wcmVjaXBfc2Vhc29uYWxpdHlfZGYuY3N2IikpCgp0ZWN0X2h1dHRfcHJlY2lwX3NlYXNvbmFsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBzZWFzX3ByZWNpcF9kZl90ZWN0X2h1dHQsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBwcmVjaXBfc2Vhc29uYWxpdHksIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCnRlY3RfaHV0dF9wcmVjaXBfc2Vhc29uYWxpdHlfcGxvdAoKZ2dzYXZlKAogICJ0ZWN0X2h1dHRfcHJlY2lwX3NlYXNvbmFsaXR5LnBuZyIsCiAgcGxvdCA9IHRlY3RfaHV0dF9wcmVjaXBfc2Vhc29uYWxpdHlfcGxvdCwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKCnNlYXNfdGVtcF9hc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW80LCB0ZWN0X2h1dHRfbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zZWFzb25hbGl0eSIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpzZWFzX3RlbXBfc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3QodyRiaW80LCB0ZWN0X2h1dHRfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3NlYXNvbmFsaXR5IikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKc2Vhc190ZW1wX2RmX3RlY3RfaHV0dCA8LSBiaW5kX3Jvd3Moc2Vhc190ZW1wX2FzZXh1YWxfdGVjdF9odXR0LCBzZWFzX3RlbXBfc2V4dWFsX3RlY3RfaHV0dCkKCnJlYWRyOjp3cml0ZV9jc3Yoc2Vhc190ZW1wX2RmX3RlY3RfaHV0dCwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3RlbXBfc2Vhc29uYWxpdHlfZGYuY3N2IikpCgp0ZWN0X2h1dHRfdGVtcF9zZWFzb25hbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gc2Vhc190ZW1wX2RmX3RlY3RfaHV0dCwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHRlbXBfc2Vhc29uYWxpdHksIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCnRlY3RfaHV0dF90ZW1wX3NlYXNvbmFsaXR5X3Bsb3QKCmdnc2F2ZSgKICAidGVjdF9odXR0X3RlbXBfc2Vhc29uYWxpdHkucG5nIiwKICBwbG90ID0gdGVjdF9odXR0X3RlbXBfc2Vhc29uYWxpdHlfcGxvdCwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKYGBgCgojIyMjIyBNb3ZlIG91dHB1dApQdXQgYWxsIG91dHB1dCBpbnRvIHNwZWNpZXMtc3BlY2lmaWMgc3ViZm9sZGVycy4KYGBge3IgcmVzdWx0cz0iaGlkZSJ9CnRlY3RfaHV0dF9vdXRfaW50X3BhdGggPC0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJ0ZWN0YXJjaHVzX2h1dHRvbmkiKQp0ZWN0X2h1dHRfb3V0X3Bsb3RfcGF0aCA8LSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdGFyY2h1c19odXR0b25pIikKdGVjdF9odXR0X291dF9zcHJlYWRfcGF0aCA8LSBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0YXJjaHVzX2h1dHRvbmkiKQp0ZWN0X2h1dHRfb3V0X29ial9wYXRoIDwtIGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3RhcmNodXNfaHV0dG9uaSIpCgojIG1vdmUgaW50ZXJhY3RpdmUKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBpbnRlcmFjdGl2ZV9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSB0ZWN0X2h1dHRfb3V0X2ludF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJ0ZWN0X2h1dHQiKQojIG1vdmUgcGxvdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBwbG90X3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IHRlY3RfaHV0dF9vdXRfcGxvdF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJ0ZWN0X2h1dHQiKQoKIyBtb3ZlIHNwcmVhZHNoZWV0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHNwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSB0ZWN0X2h1dHRfb3V0X3NwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJ0ZWN0X2h1dHQiKQoKIyBtb3ZlIG9iamVjdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBvYmpfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gdGVjdF9odXR0X291dF9vYmpfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAidGVjdF9odXR0IikKYGBgCgoKIyMgQ29udmVuaWVuY2Ugc2NyaXB0cwoqVGhlc2Ugc2NyaXB0cyBhcmVuJ3QgY3J1Y2lhbCBmb3IgcmVwcm9kdWNpbmcgdGhpcyBhbmFseXNpcywgYnV0IHdlcmUgaGVscGZ1bCBmb3IgdmFyaW91cyByZWFzb25zLiBTb21lIG9mIHRoZXNlIGhhdmUgaGFyZC1jb2RlZCBwYXRocyBhbmQgc3VjaCwgc28gbm8gZ3VhcmFudGVlcyBmb3IgdXNlIHJpZ2h0IG91dCBvZiB0aGUgYm94LioKCgpUaGlzIHdhcyBhIHNjcmlwdCBJIHVzZWQgdG8gdGFrZSBmdWxsIGNoZWxzYSBmaWxlcywgY3JvcCB0aGVtIHRvIE5ldyBaZWFsYW5kIGV4dGVudCwgYW5kIHdyaXRlIHRoZW0gdG8gYSBmaWxlIHdpdGggbXkgcGVyc29uYWwgY29tcHV0ZXIuIEkgZG9uJ3QgaGF2ZSBtdWNoIG1lbW9yeSwgc28gdW56aXBwaW5nIHRvIGEgdGVtcG9yYXJ5IGRpcmVjdG9yeSwgdGhlbiBkZWxldGluZyB0aGUgZGlyZWN0b3J5IHRvIGZyZWUgdXAgc3BhY2UgZm9yIHRoZSBsYXJnZSBmaWxlcyB3b3JrZWQuIApgYGB7ciBldmFsPUZBTFNFfQojIyBnZXQgY2hlbHNhIGRhdGEKY2hlbHNhX2ZvbGRlciA8LSAiL1VzZXJzL2Nvbm5vcmZyZW5jaC9Ecm9wYm94L09sZF9NYWMvY2xpbWF0ZS1kYXRhL2NoZWxzYV8zMHNfYmlvIgp6aXBfZmlsZXMgPC0gbGlzdC5maWxlcyhjaGVsc2FfZm9sZGVyLCBmdWxsLm5hbWVzID0gVFJVRSkKCiMgdXNpbmcgdGhlIFVuYXJjaGl2ZXIgY29tbWFuZGxpbmUgdG9vbHMgZm9yIE1hYyB0byB1bnppcCB0aGUgN3ppcCBjaGVsc2EgbGF5ZXJzLiBSZWd1bGFyIHVuemlwKCkgZG9lcyBub3Qgd29yayB3aXRoIDd6IHppcHBlZCBmaWxlcwpmb3IgKGZpbGUgaW4gemlwX2ZpbGVzKSB7CiAgIyBzZXQgdGVtcCBkaXJlY3RvcnkKICB0ZW1wZCA8LSB0ZW1wZGlyKCkKICBzeXN0ZW0ocGFzdGUoInVuYXIiLCBmaWxlLCAiLW8iLCB0ZW1wZCkpCiAgciA8LSByYXN0ZXIobGlzdC5maWxlcyh0ZW1wZCwgcGF0dGVybiA9ICIqLnRpZiIsIGZ1bGwubmFtZXMgPSBUUlVFKSkgJT4lCiAgICBjcm9wKGV4dGVudCgxNjYsIDE3OSwgLTQ4LCAtMzQpKQogIHdyaXRlUmFzdGVyKHIsIGZpbGVuYW1lID0gcGFzdGUwKCJ+L0Rlc2t0b3AvIiwgbGlzdC5maWxlcyh0ZW1wZCwgcGF0dGVybiA9ICIqLmFzYyIpKSwgZm9ybWF0ID0gImFzY2lpIikKICB1bmxpbmsodGVtcGQsIHJlY3Vyc2l2ZSA9IFRSVUUpCn0KYGBgCgo=